source: frontend/node_modules/diff-sequences/perf/index.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8// Make sure to run node with --expose-gc option!
9
10// The times are reliable if about 1% relative mean error if you run it:
11
12// * immediately after restart
13// * with 100% battery charge
14// * not connected to network
15
16/* eslint import/no-extraneous-dependencies: "off" */
17
18const Benchmark = require('benchmark');
19const diffBaseline = require('diff').diffLines;
20const diffImproved = require('../build/index.js').default;
21
22const testBaseline = (a, b) => {
23 const benchmark = new Benchmark({
24 fn() {
25 diffBaseline(a, b);
26 },
27 name: 'baseline',
28 onCycle() {
29 global.gc(); // after run cycle
30 },
31 onStart() {
32 global.gc(); // when benchmark starts
33 },
34 });
35
36 benchmark.run({async: false});
37
38 return benchmark.stats;
39};
40
41const testImproved = function (a, b) {
42 const benchmark = new Benchmark({
43 fn() {
44 // Split string arguments to make fair comparison with baseline.
45 const aItems = a.split('\n');
46 const bItems = b.split('\n');
47
48 const isCommon = (aIndex, bIndex) => aItems[aIndex] === bItems[bIndex];
49
50 // This callback obviously does less than baseline `diff` package,
51 // but avoiding double work and memory churn is the goal.
52 // For example, `jest-diff` has had to split strings that `diff` joins.
53 const foundSubsequence = () => {};
54
55 diffImproved(aItems.length, bItems.length, isCommon, foundSubsequence);
56 },
57 name: 'improved',
58 onCycle() {
59 global.gc(); // after run cycle
60 },
61 onStart() {
62 global.gc(); // when benchmark starts
63 },
64 });
65
66 benchmark.run({async: false});
67
68 return benchmark.stats;
69};
70
71const writeHeading2 = () => {
72 console.log('## Benchmark time for `diff-sequences` versus `diff`\n');
73 console.log('A ratio less than 1.0 means `diff-sequences` is faster.');
74};
75
76const writeHeading3 = n => {
77 console.log(`\n### n = ${n}\n`);
78 console.log('| name | % | ratio | improved | rme | baseline | rme |');
79 console.log('| :--- | ---: | :--- | :--- | ---: | :--- | ---: |');
80};
81
82const writeRow = (name, percent, statsImproved, statsBaseline) => {
83 const {mean: meanImproved, rme: rmeImproved} = statsImproved;
84 const {mean: meanBaseline, rme: rmeBaseline} = statsBaseline;
85 const ratio = meanImproved / meanBaseline;
86
87 console.log(
88 `| ${name} | ${percent}% | ${ratio.toFixed(
89 4,
90 )} | ${meanImproved.toExponential(4)} | ${rmeImproved.toFixed(
91 2,
92 )}% | ${meanBaseline.toExponential(4)} | ${rmeBaseline.toFixed(2)}% |`,
93 );
94};
95
96const testDeleteInsert = (tenths, more, less) => {
97 // For improved `diff-sequences` package, delete is often slower than insert.
98 const statsDeleteImproved = testImproved(more, less);
99 const statsDeleteBaseline = testBaseline(more, less);
100 writeRow('delete', tenths * 10, statsDeleteImproved, statsDeleteBaseline);
101
102 // For baseline `diff` package, many insertions is serious perf problem.
103 // However, the benchmark package cannot accurately measure for large n.
104 const statsInsertBaseline = testBaseline(less, more);
105 const statsInsertImproved = testImproved(less, more);
106 writeRow('insert', tenths * 10, statsInsertImproved, statsInsertBaseline);
107};
108
109const testChange = (tenths, expected, received) => {
110 const statsImproved = testImproved(expected, received);
111 const statsBaseline = testBaseline(expected, received);
112 writeRow('change', tenths * 10, statsImproved, statsBaseline);
113};
114
115const getItems = (n, callback) => {
116 const items = [];
117
118 for (let i = 0; i !== n; i += 1) {
119 const item = callback(i);
120 if (typeof item === 'string') {
121 items.push(item);
122 }
123 }
124
125 return items.join('\n');
126};
127
128// Simulate change of property name which is usually not same line.
129// Expected: 0 1 2 3 4 5 6 7 8 9 and so on
130// Received: 1 2 3 4 x0 5 6 7 8 9 and so on
131const change2 = i => {
132 const j = i % 10;
133 return j === 4 ? `x${i - 4}` : j < 4 ? `${i + 1}` : `${i}`;
134};
135
136const testLength = n => {
137 const all = getItems(n, i => `${i}`);
138
139 writeHeading3(n);
140
141 [2, 4, 8].forEach(tenth => {
142 testDeleteInsert(
143 tenth,
144 all,
145 getItems(n, i => i % 10 >= tenth && `${i}`),
146 );
147 });
148 testChange(
149 1,
150 all,
151 getItems(n, i => (i % 10 === 0 ? `x${i}` : `${i}`)),
152 );
153 testChange(2, all, getItems(n, change2));
154 testChange(
155 5,
156 all,
157 getItems(n, i => (i % 2 === 0 ? `x${i}` : `${i}`)),
158 );
159 testChange(
160 10,
161 all,
162 getItems(n, i => `x${i}`),
163 ); // simulate TDD
164};
165
166writeHeading2();
167
168testLength(20);
169testLength(200);
170testLength(2000);
Note: See TracBrowser for help on using the repository browser.