Skip to content

Commit f82e56e

Browse files
perf: various performance improvements (#17135)
* perf: addParensIndent replaced shifting with reverse iteration * perf: changed string handling from regex to manual parsing * refactor: more explicit * perf: remove unnessisary array and object creation * pref: opimized out reduce for basic iteration * perf: replaced reduce with basic iteration * perf: optimized unessisary array creation and objects * perf: replaced reduce with basic iteration * perf: replaced reduce with basic iteration * perf: replaced filter with basic loop for counting valid elements * perf: removed array creation in indent program exit
1 parent da81e66 commit f82e56e

8 files changed

Lines changed: 203 additions & 173 deletions

File tree

lib/cli-engine/cli-engine.js

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,17 @@ function validateFixTypes(fixTypes) {
158158
* @private
159159
*/
160160
function calculateStatsPerFile(messages) {
161-
return messages.reduce((stat, message) => {
161+
const stat = {
162+
errorCount: 0,
163+
fatalErrorCount: 0,
164+
warningCount: 0,
165+
fixableErrorCount: 0,
166+
fixableWarningCount: 0
167+
};
168+
169+
for (let i = 0; i < messages.length; i++) {
170+
const message = messages[i];
171+
162172
if (message.fatal || message.severity === 2) {
163173
stat.errorCount++;
164174
if (message.fatal) {
@@ -173,14 +183,8 @@ function calculateStatsPerFile(messages) {
173183
stat.fixableWarningCount++;
174184
}
175185
}
176-
return stat;
177-
}, {
178-
errorCount: 0,
179-
fatalErrorCount: 0,
180-
warningCount: 0,
181-
fixableErrorCount: 0,
182-
fixableWarningCount: 0
183-
});
186+
}
187+
return stat;
184188
}
185189

186190
/**
@@ -190,20 +194,25 @@ function calculateStatsPerFile(messages) {
190194
* @private
191195
*/
192196
function calculateStatsPerRun(results) {
193-
return results.reduce((stat, result) => {
194-
stat.errorCount += result.errorCount;
195-
stat.fatalErrorCount += result.fatalErrorCount;
196-
stat.warningCount += result.warningCount;
197-
stat.fixableErrorCount += result.fixableErrorCount;
198-
stat.fixableWarningCount += result.fixableWarningCount;
199-
return stat;
200-
}, {
197+
const stat = {
201198
errorCount: 0,
202199
fatalErrorCount: 0,
203200
warningCount: 0,
204201
fixableErrorCount: 0,
205202
fixableWarningCount: 0
206-
});
203+
};
204+
205+
for (let i = 0; i < results.length; i++) {
206+
const result = results[i];
207+
208+
stat.errorCount += result.errorCount;
209+
stat.fatalErrorCount += result.fatalErrorCount;
210+
stat.warningCount += result.warningCount;
211+
stat.fixableErrorCount += result.fixableErrorCount;
212+
stat.fixableWarningCount += result.fixableWarningCount;
213+
}
214+
215+
return stat;
207216
}
208217

209218
/**

lib/eslint/flat-eslint.js

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,17 @@ const importedConfigFileModificationTime = new Map();
103103
* @private
104104
*/
105105
function calculateStatsPerFile(messages) {
106-
return messages.reduce((stat, message) => {
106+
const stat = {
107+
errorCount: 0,
108+
fatalErrorCount: 0,
109+
warningCount: 0,
110+
fixableErrorCount: 0,
111+
fixableWarningCount: 0
112+
};
113+
114+
for (let i = 0; i < messages.length; i++) {
115+
const message = messages[i];
116+
107117
if (message.fatal || message.severity === 2) {
108118
stat.errorCount++;
109119
if (message.fatal) {
@@ -118,14 +128,8 @@ function calculateStatsPerFile(messages) {
118128
stat.fixableWarningCount++;
119129
}
120130
}
121-
return stat;
122-
}, {
123-
errorCount: 0,
124-
fatalErrorCount: 0,
125-
warningCount: 0,
126-
fixableErrorCount: 0,
127-
fixableWarningCount: 0
128-
});
131+
}
132+
return stat;
129133
}
130134

131135
/**
@@ -135,20 +139,24 @@ function calculateStatsPerFile(messages) {
135139
* @private
136140
*/
137141
function calculateStatsPerRun(results) {
138-
return results.reduce((stat, result) => {
139-
stat.errorCount += result.errorCount;
140-
stat.fatalErrorCount += result.fatalErrorCount;
141-
stat.warningCount += result.warningCount;
142-
stat.fixableErrorCount += result.fixableErrorCount;
143-
stat.fixableWarningCount += result.fixableWarningCount;
144-
return stat;
145-
}, {
142+
const stat = {
146143
errorCount: 0,
147144
fatalErrorCount: 0,
148145
warningCount: 0,
149146
fixableErrorCount: 0,
150147
fixableWarningCount: 0
151-
});
148+
};
149+
150+
for (let i = 0; i < results.length; i++) {
151+
const result = results[i];
152+
153+
stat.errorCount += result.errorCount;
154+
stat.fatalErrorCount += result.fatalErrorCount;
155+
stat.warningCount += result.warningCount;
156+
stat.fixableErrorCount += result.fixableErrorCount;
157+
stat.fixableWarningCount += result.fixableWarningCount;
158+
}
159+
return stat;
152160
}
153161

154162
/**

lib/rules/accessor-pairs.js

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -223,54 +223,46 @@ module.exports = {
223223
}
224224
}
225225

226-
/**
227-
* Creates a new `AccessorData` object for the given getter or setter node.
228-
* @param {ASTNode} node A getter or setter node.
229-
* @returns {AccessorData} New `AccessorData` object that contains the given node.
230-
* @private
231-
*/
232-
function createAccessorData(node) {
233-
const name = astUtils.getStaticPropertyName(node);
234-
const key = (name !== null) ? name : sourceCode.getTokens(node.key);
235-
236-
return {
237-
key,
238-
getters: node.kind === "get" ? [node] : [],
239-
setters: node.kind === "set" ? [node] : []
240-
};
241-
}
242-
243-
/**
244-
* Merges the given `AccessorData` object into the given accessors list.
245-
* @param {AccessorData[]} accessors The list to merge into.
246-
* @param {AccessorData} accessorData The object to merge.
247-
* @returns {AccessorData[]} The same instance with the merged object.
248-
* @private
249-
*/
250-
function mergeAccessorData(accessors, accessorData) {
251-
const equalKeyElement = accessors.find(a => areEqualKeys(a.key, accessorData.key));
252-
253-
if (equalKeyElement) {
254-
equalKeyElement.getters.push(...accessorData.getters);
255-
equalKeyElement.setters.push(...accessorData.setters);
256-
} else {
257-
accessors.push(accessorData);
258-
}
259-
260-
return accessors;
261-
}
262-
263226
/**
264227
* Checks accessor pairs in the given list of nodes.
265228
* @param {ASTNode[]} nodes The list to check.
266229
* @returns {void}
267230
* @private
268231
*/
269232
function checkList(nodes) {
270-
const accessors = nodes
271-
.filter(isAccessorKind)
272-
.map(createAccessorData)
273-
.reduce(mergeAccessorData, []);
233+
const accessors = [];
234+
let found = false;
235+
236+
for (let i = 0; i < nodes.length; i++) {
237+
const node = nodes[i];
238+
239+
if (isAccessorKind(node)) {
240+
241+
// Creates a new `AccessorData` object for the given getter or setter node.
242+
const name = astUtils.getStaticPropertyName(node);
243+
const key = (name !== null) ? name : sourceCode.getTokens(node.key);
244+
245+
// Merges the given `AccessorData` object into the given accessors list.
246+
for (let j = 0; j < accessors.length; j++) {
247+
const accessor = accessors[j];
248+
249+
if (areEqualKeys(accessor.key, key)) {
250+
accessor.getters.push(...node.kind === "get" ? [node] : []);
251+
accessor.setters.push(...node.kind === "set" ? [node] : []);
252+
found = true;
253+
break;
254+
}
255+
}
256+
if (!found) {
257+
accessors.push({
258+
key,
259+
getters: node.kind === "get" ? [node] : [],
260+
setters: node.kind === "set" ? [node] : []
261+
});
262+
}
263+
found = false;
264+
}
265+
}
274266

275267
for (const { getters, setters } of accessors) {
276268
if (checkSetWithoutGet && setters.length && !getters.length) {

lib/rules/array-element-newline.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,19 +240,25 @@ module.exports = {
240240
.some(element => element.loc.start.line !== element.loc.end.line);
241241
}
242242

243-
const linebreaksCount = node.elements.map((element, i) => {
243+
let linebreaksCount = 0;
244+
245+
for (let i = 0; i < node.elements.length; i++) {
246+
const element = node.elements[i];
247+
244248
const previousElement = elements[i - 1];
245249

246250
if (i === 0 || element === null || previousElement === null) {
247-
return false;
251+
continue;
248252
}
249253

250254
const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken);
251255
const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken);
252256
const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken);
253257

254-
return !astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement);
255-
}).filter(isBreak => isBreak === true).length;
258+
if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) {
259+
linebreaksCount++;
260+
}
261+
}
256262

257263
const needsLinebreaks = (
258264
elements.length >= options.minItems ||

lib/rules/grouped-accessor-pairs.js

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -137,43 +137,6 @@ module.exports = {
137137
});
138138
}
139139

140-
/**
141-
* Creates a new `AccessorData` object for the given getter or setter node.
142-
* @param {ASTNode} node A getter or setter node.
143-
* @returns {AccessorData} New `AccessorData` object that contains the given node.
144-
* @private
145-
*/
146-
function createAccessorData(node) {
147-
const name = astUtils.getStaticPropertyName(node);
148-
const key = (name !== null) ? name : sourceCode.getTokens(node.key);
149-
150-
return {
151-
key,
152-
getters: node.kind === "get" ? [node] : [],
153-
setters: node.kind === "set" ? [node] : []
154-
};
155-
}
156-
157-
/**
158-
* Merges the given `AccessorData` object into the given accessors list.
159-
* @param {AccessorData[]} accessors The list to merge into.
160-
* @param {AccessorData} accessorData The object to merge.
161-
* @returns {AccessorData[]} The same instance with the merged object.
162-
* @private
163-
*/
164-
function mergeAccessorData(accessors, accessorData) {
165-
const equalKeyElement = accessors.find(a => areEqualKeys(a.key, accessorData.key));
166-
167-
if (equalKeyElement) {
168-
equalKeyElement.getters.push(...accessorData.getters);
169-
equalKeyElement.setters.push(...accessorData.setters);
170-
} else {
171-
accessors.push(accessorData);
172-
}
173-
174-
return accessors;
175-
}
176-
177140
/**
178141
* Checks accessor pairs in the given list of nodes.
179142
* @param {ASTNode[]} nodes The list to check.
@@ -182,11 +145,39 @@ module.exports = {
182145
* @private
183146
*/
184147
function checkList(nodes, shouldCheck) {
185-
const accessors = nodes
186-
.filter(shouldCheck)
187-
.filter(isAccessorKind)
188-
.map(createAccessorData)
189-
.reduce(mergeAccessorData, []);
148+
const accessors = [];
149+
let found = false;
150+
151+
for (let i = 0; i < nodes.length; i++) {
152+
const node = nodes[i];
153+
154+
if (shouldCheck(node) && isAccessorKind(node)) {
155+
156+
// Creates a new `AccessorData` object for the given getter or setter node.
157+
const name = astUtils.getStaticPropertyName(node);
158+
const key = (name !== null) ? name : sourceCode.getTokens(node.key);
159+
160+
// Merges the given `AccessorData` object into the given accessors list.
161+
for (let j = 0; j < accessors.length; j++) {
162+
const accessor = accessors[j];
163+
164+
if (areEqualKeys(accessor.key, key)) {
165+
accessor.getters.push(...node.kind === "get" ? [node] : []);
166+
accessor.setters.push(...node.kind === "set" ? [node] : []);
167+
found = true;
168+
break;
169+
}
170+
}
171+
if (!found) {
172+
accessors.push({
173+
key,
174+
getters: node.kind === "get" ? [node] : [],
175+
setters: node.kind === "set" ? [node] : []
176+
});
177+
}
178+
found = false;
179+
}
180+
}
190181

191182
for (const { getters, setters } of accessors) {
192183

0 commit comments

Comments
 (0)