Skip to content

Commit

Permalink
Replace 'Array.reduce' with 'for of' (#2988)
Browse files Browse the repository at this point in the history
Results in measurable perfomance increase and significantly lower memory
usage in a few benchmarks.
  • Loading branch information
IvanGoncharov committed Mar 25, 2021
1 parent 494a3d2 commit 2f876b6
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 54 deletions.
16 changes: 8 additions & 8 deletions src/error/GraphQLError.js
Expand Up @@ -102,12 +102,12 @@ export class GraphQLError extends Error {

let _positions = positions;
if (!_positions && _nodes) {
_positions = _nodes.reduce((list, node) => {
_positions = [];
for (const node of _nodes) {
if (node.loc) {
list.push(node.loc.start);
_positions.push(node.loc.start);
}
return list;
}, []);
}
}
if (_positions && _positions.length === 0) {
_positions = undefined;
Expand All @@ -117,12 +117,12 @@ export class GraphQLError extends Error {
if (positions && source) {
_locations = positions.map((pos) => getLocation(source, pos));
} else if (_nodes) {
_locations = _nodes.reduce((list, node) => {
_locations = [];
for (const node of _nodes) {
if (node.loc) {
list.push(getLocation(node.loc.source, node.loc.start));
_locations.push(getLocation(node.loc.source, node.loc.start));
}
return list;
}, []);
}
}

let _extensions = extensions;
Expand Down
9 changes: 5 additions & 4 deletions src/jsutils/keyMap.js
Expand Up @@ -27,8 +27,9 @@ export function keyMap<T>(
list: $ReadOnlyArray<T>,
keyFn: (item: T) => string,
): ObjMap<T> {
return list.reduce((map, item) => {
map[keyFn(item)] = item;
return map;
}, Object.create(null));
const result = Object.create(null);
for (const item of list) {
result[keyFn(item)] = item;
}
return result;
}
9 changes: 5 additions & 4 deletions src/jsutils/keyValMap.js
Expand Up @@ -22,8 +22,9 @@ export function keyValMap<T, V>(
keyFn: (item: T) => string,
valFn: (item: T) => V,
): ObjMap<V> {
return list.reduce((map, item) => {
map[keyFn(item)] = valFn(item);
return map;
}, Object.create(null));
const result = Object.create(null);
for (const item of list) {
result[keyFn(item)] = valFn(item);
}
return result;
}
15 changes: 7 additions & 8 deletions src/jsutils/promiseForObject.js
Expand Up @@ -10,12 +10,11 @@ import type { ObjMap } from './ObjMap';
export function promiseForObject<T>(
object: ObjMap<Promise<T>>,
): Promise<ObjMap<T>> {
const keys = Object.keys(object);
const valuesAndPromises = keys.map((name) => object[name]);
return Promise.all(valuesAndPromises).then((values) =>
values.reduce((resolvedObject, value, i) => {
resolvedObject[keys[i]] = value;
return resolvedObject;
}, Object.create(null)),
);
return Promise.all(Object.values(object)).then((resolvedValues) => {
const resolvedObject = Object.create(null);
for (const [i, key] of Object.keys(object).entries()) {
resolvedObject[key] = resolvedValues[i];
}
return resolvedObject;
});
}
14 changes: 3 additions & 11 deletions src/language/experimentalOnlineParser/onlineParser.js
Expand Up @@ -389,17 +389,9 @@ export class OnlineParser {
): boolean {
if (rule.butNot) {
if (Array.isArray(rule.butNot)) {
if (
rule.butNot.reduce(
(matched, constraint) =>
matched || this._matchToken(token, constraint),
false,
)
) {
return false;
}

return true;
return !rule.butNot.some((constraint) =>
this._matchToken(token, constraint),
);
}

return !this._matchToken(token, rule.butNot);
Expand Down
20 changes: 8 additions & 12 deletions src/validation/ValidationContext.js
Expand Up @@ -67,19 +67,15 @@ export class ASTValidationContext {
}

getFragment(name: string): ?FragmentDefinitionNode {
let fragments = this._fragments;
if (!fragments) {
this._fragments = fragments = this.getDocument().definitions.reduce(
(frags, statement) => {
if (statement.kind === Kind.FRAGMENT_DEFINITION) {
frags[statement.name.value] = statement;
}
return frags;
},
Object.create(null),
);
if (!this._fragments) {
const fragments = (this._fragments = Object.create(null));
for (const defNode of this.getDocument().definitions) {
if (defNode.kind === Kind.FRAGMENT_DEFINITION) {
fragments[defNode.name.value] = defNode;
}
}
}
return fragments[name];
return this._fragments[name];
}

getFragmentSpreads(
Expand Down
9 changes: 2 additions & 7 deletions src/validation/rules/OverlappingFieldsCanBeMergedRule.js
Expand Up @@ -775,13 +775,8 @@ function subfieldConflicts(
if (conflicts.length > 0) {
return [
[responseName, conflicts.map(([reason]) => reason)],
conflicts.reduce((allFields, [, fields1]) => allFields.concat(fields1), [
node1,
]),
conflicts.reduce(
(allFields, [, , fields2]) => allFields.concat(fields2),
[node2],
),
[node1, ...conflicts.map(([, fields1]) => fields1).flat()],
[node2, ...conflicts.map(([, , fields2]) => fields2).flat()],
];
}
}
Expand Down

0 comments on commit 2f876b6

Please sign in to comment.