|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const Benchmark = require('benchmark'); |
|
|
const diffBaseline = require('diff').diffLines; |
|
|
const diffImproved = require('../build/index.js').default; |
|
|
|
|
|
const testBaseline = (a, b) => { |
|
|
const benchmark = new Benchmark({ |
|
|
fn() { |
|
|
diffBaseline(a, b); |
|
|
}, |
|
|
name: 'baseline', |
|
|
onCycle() { |
|
|
global.gc(); |
|
|
}, |
|
|
onStart() { |
|
|
global.gc(); |
|
|
}, |
|
|
}); |
|
|
|
|
|
benchmark.run({async: false}); |
|
|
|
|
|
return benchmark.stats; |
|
|
}; |
|
|
|
|
|
const testImproved = function (a, b) { |
|
|
const benchmark = new Benchmark({ |
|
|
fn() { |
|
|
|
|
|
const aItems = a.split('\n'); |
|
|
const bItems = b.split('\n'); |
|
|
|
|
|
const isCommon = (aIndex, bIndex) => aItems[aIndex] === bItems[bIndex]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const foundSubsequence = () => {}; |
|
|
|
|
|
diffImproved(aItems.length, bItems.length, isCommon, foundSubsequence); |
|
|
}, |
|
|
name: 'improved', |
|
|
onCycle() { |
|
|
global.gc(); |
|
|
}, |
|
|
onStart() { |
|
|
global.gc(); |
|
|
}, |
|
|
}); |
|
|
|
|
|
benchmark.run({async: false}); |
|
|
|
|
|
return benchmark.stats; |
|
|
}; |
|
|
|
|
|
const writeHeading2 = () => { |
|
|
console.log('## Benchmark time for `diff-sequences` versus `diff`\n'); |
|
|
console.log('A ratio less than 1.0 means `diff-sequences` is faster.'); |
|
|
}; |
|
|
|
|
|
const writeHeading3 = n => { |
|
|
console.log(`\n### n = ${n}\n`); |
|
|
console.log('| name | % | ratio | improved | rme | baseline | rme |'); |
|
|
console.log('| :--- | ---: | :--- | :--- | ---: | :--- | ---: |'); |
|
|
}; |
|
|
|
|
|
const writeRow = (name, percent, statsImproved, statsBaseline) => { |
|
|
const {mean: meanImproved, rme: rmeImproved} = statsImproved; |
|
|
const {mean: meanBaseline, rme: rmeBaseline} = statsBaseline; |
|
|
const ratio = meanImproved / meanBaseline; |
|
|
|
|
|
console.log( |
|
|
`| ${name} | ${percent}% | ${ratio.toFixed( |
|
|
4, |
|
|
)} | ${meanImproved.toExponential(4)} | ${rmeImproved.toFixed( |
|
|
2, |
|
|
)}% | ${meanBaseline.toExponential(4)} | ${rmeBaseline.toFixed(2)}% |`, |
|
|
); |
|
|
}; |
|
|
|
|
|
const testDeleteInsert = (tenths, more, less) => { |
|
|
|
|
|
const statsDeleteImproved = testImproved(more, less); |
|
|
const statsDeleteBaseline = testBaseline(more, less); |
|
|
writeRow('delete', tenths * 10, statsDeleteImproved, statsDeleteBaseline); |
|
|
|
|
|
|
|
|
|
|
|
const statsInsertBaseline = testBaseline(less, more); |
|
|
const statsInsertImproved = testImproved(less, more); |
|
|
writeRow('insert', tenths * 10, statsInsertImproved, statsInsertBaseline); |
|
|
}; |
|
|
|
|
|
const testChange = (tenths, expected, received) => { |
|
|
const statsImproved = testImproved(expected, received); |
|
|
const statsBaseline = testBaseline(expected, received); |
|
|
writeRow('change', tenths * 10, statsImproved, statsBaseline); |
|
|
}; |
|
|
|
|
|
const getItems = (n, callback) => { |
|
|
const items = []; |
|
|
|
|
|
for (let i = 0; i !== n; i += 1) { |
|
|
const item = callback(i); |
|
|
if (typeof item === 'string') { |
|
|
items.push(item); |
|
|
} |
|
|
} |
|
|
|
|
|
return items.join('\n'); |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const change2 = i => { |
|
|
const j = i % 10; |
|
|
return j === 4 ? `x${i - 4}` : j < 4 ? `${i + 1}` : `${i}`; |
|
|
}; |
|
|
|
|
|
const testLength = n => { |
|
|
const all = getItems(n, i => `${i}`); |
|
|
|
|
|
writeHeading3(n); |
|
|
|
|
|
[2, 4, 8].forEach(tenth => { |
|
|
testDeleteInsert( |
|
|
tenth, |
|
|
all, |
|
|
getItems(n, i => i % 10 >= tenth && `${i}`), |
|
|
); |
|
|
}); |
|
|
testChange( |
|
|
1, |
|
|
all, |
|
|
getItems(n, i => (i % 10 === 0 ? `x${i}` : `${i}`)), |
|
|
); |
|
|
testChange(2, all, getItems(n, change2)); |
|
|
testChange( |
|
|
5, |
|
|
all, |
|
|
getItems(n, i => (i % 2 === 0 ? `x${i}` : `${i}`)), |
|
|
); |
|
|
testChange( |
|
|
10, |
|
|
all, |
|
|
getItems(n, i => `x${i}`), |
|
|
); |
|
|
}; |
|
|
|
|
|
writeHeading2(); |
|
|
|
|
|
testLength(20); |
|
|
testLength(200); |
|
|
testLength(2000); |
|
|
|