Skip to content

Commit 6696f57

Browse files
perf: use improved comparison algorithm
This change reduces the time for this rule on the eslint repo down from 453ms to 46ms (= roughly 8x faster).
1 parent 305c7cd commit 6696f57

File tree

1 file changed

+14
-37
lines changed

1 file changed

+14
-37
lines changed

lib/rules/no-identical-tests.js

+14-37
Original file line numberDiff line numberDiff line change
@@ -34,52 +34,29 @@ module.exports = {
3434
// ----------------------------------------------------------------------
3535
const sourceCode = context.getSourceCode();
3636

37-
// ----------------------------------------------------------------------
38-
// Helpers
39-
// ----------------------------------------------------------------------
4037
/**
41-
*compare two test cases despite of properties order.
42-
*@returns {boolean} if eq, return true, else return false.
38+
* Create a unique cache key
39+
* @param {object} test
40+
* @returns {string}
4341
*/
44-
function eq(testA, testB) {
45-
if (testA.type !== testB.type) {
46-
return false;
47-
}
48-
49-
if (testA.type !== 'ObjectExpression') {
50-
return sourceCode.getText(testA) === sourceCode.getText(testB);
51-
}
52-
53-
const propertiesA = testA.properties;
54-
const propertiesB = testB.properties;
55-
56-
// if properties length not eq; return false;
57-
if (propertiesA.length !== propertiesB.length) {
58-
return false;
59-
}
60-
61-
const propertiesSetA = new Set();
62-
propertiesA.forEach((item) => {
63-
const code = sourceCode.getText(item);
64-
propertiesSetA.add(code);
65-
});
66-
67-
for (const element of propertiesB) {
68-
const code = sourceCode.getText(element);
69-
if (!propertiesSetA.has(code)) {
70-
return false;
71-
}
42+
function toKey(test) {
43+
if (test.type !== 'ObjectExpression') {
44+
return JSON.stringify([test.type, sourceCode.getText(test)]);
7245
}
73-
return true;
46+
return JSON.stringify([
47+
test.type,
48+
...test.properties.map((p) => sourceCode.getText(p)).sort(),
49+
]);
7450
}
7551

7652
return {
7753
Program(ast) {
7854
utils.getTestInfo(context, ast).forEach((testRun) => {
7955
[testRun.valid, testRun.invalid].forEach((tests) => {
80-
const cache = [];
56+
const cache = new Set();
8157
tests.forEach((test) => {
82-
if (cache.some((item) => eq(item, test))) {
58+
const key = toKey(test);
59+
if (cache.has(key)) {
8360
context.report({
8461
node: test,
8562
messageId: 'identical',
@@ -96,7 +73,7 @@ module.exports = {
9673
},
9774
});
9875
} else {
99-
cache.push(test);
76+
cache.add(key);
10077
}
10178
});
10279
});

0 commit comments

Comments
 (0)