diff options
author | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 |
---|---|---|
committer | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 |
commit | 5d309ff52cd399a6b71968a6b9a70c8ac0b98981 (patch) | |
tree | 360f7eb50f956e2367ef38fa1fc6ac7ac5258042 /node_modules/diff-sequences/perf/index.js | |
parent | b500a50f1b97d93c98b36ed9a980f8188d648147 (diff) | |
download | LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.tar.gz LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.zip |
Added node_modules for the updating to work properly.
Diffstat (limited to 'node_modules/diff-sequences/perf/index.js')
-rw-r--r-- | node_modules/diff-sequences/perf/index.js | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/node_modules/diff-sequences/perf/index.js b/node_modules/diff-sequences/perf/index.js new file mode 100644 index 0000000..5673f9d --- /dev/null +++ b/node_modules/diff-sequences/perf/index.js @@ -0,0 +1,170 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// Make sure to run node with --expose-gc option! + +// The times are reliable if about 1% relative mean error if you run it: + +// * immediately after restart +// * with 100% battery charge +// * not connected to network + +/* eslint import/no-extraneous-dependencies: "off" */ + +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(); // after run cycle + }, + onStart() { + global.gc(); // when benchmark starts + }, + }); + + benchmark.run({async: false}); + + return benchmark.stats; +}; + +const testImproved = function (a, b) { + const benchmark = new Benchmark({ + fn() { + // Split string arguments to make fair comparison with baseline. + const aItems = a.split('\n'); + const bItems = b.split('\n'); + + const isCommon = (aIndex, bIndex) => aItems[aIndex] === bItems[bIndex]; + + // This callback obviously does less than baseline `diff` package, + // but avoiding double work and memory churn is the goal. + // For example, `jest-diff` has had to split strings that `diff` joins. + const foundSubsequence = () => {}; + + diffImproved(aItems.length, bItems.length, isCommon, foundSubsequence); + }, + name: 'improved', + onCycle() { + global.gc(); // after run cycle + }, + onStart() { + global.gc(); // when benchmark starts + }, + }); + + 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) => { + // For improved `diff-sequences` package, delete is often slower than insert. + const statsDeleteImproved = testImproved(more, less); + const statsDeleteBaseline = testBaseline(more, less); + writeRow('delete', tenths * 10, statsDeleteImproved, statsDeleteBaseline); + + // For baseline `diff` package, many insertions is serious perf problem. + // However, the benchmark package cannot accurately measure for large n. + 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'); +}; + +// Simulate change of property name which is usually not same line. +// Expected: 0 1 2 3 4 5 6 7 8 9 and so on +// Received: 1 2 3 4 x0 5 6 7 8 9 and so on +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}`), + ); // simulate TDD +}; + +writeHeading2(); + +testLength(20); +testLength(200); +testLength(2000); |