Reduce unnecessary usage of Array.prototype.concat()

There are obviously cases where using `concat` makes perfect sense, since that method doesn't change any of the existing Arrays; see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

However, in a few cases throughout the code-base that's not an issue and using `concat` only leads to unnecessary intermediate allocations. With modern JavaScript we can thus replace those with a combination of `push` and spread-syntax, which wasn't originally possible when the code was written.
This commit is contained in:
Jonas Jenwald 2022-06-19 12:26:48 +02:00
parent f516bb2174
commit c21f4faaf8
4 changed files with 21 additions and 23 deletions

View File

@ -220,10 +220,11 @@ function postprocessNode(ctx, node) {
case "BlockStatement": case "BlockStatement":
// Block statements inside a block are moved to the parent one. // Block statements inside a block are moved to the parent one.
const subChildren = node.body[subExpressionIndex].body; const subChildren = node.body[subExpressionIndex].body;
Array.prototype.splice.apply( Array.prototype.splice.apply(node.body, [
node.body, subExpressionIndex,
[subExpressionIndex, 1].concat(subChildren) 1,
); ...subChildren,
]);
subExpressionIndex += Math.max(subChildren.length - 1, 0); subExpressionIndex += Math.max(subChildren.length - 1, 0);
continue; continue;
case "ReturnStatement": case "ReturnStatement":

View File

@ -1387,7 +1387,7 @@ class CFFCompiler {
const output = { const output = {
data: [], data: [],
length: 0, length: 0,
add: function CFFCompiler_add(data) { add(data) {
this.data = this.data.concat(data); this.data = this.data.concat(data);
this.length = this.data.length; this.length = this.data.length;
}, },
@ -1680,7 +1680,7 @@ class CFFCompiler {
} }
compileDict(dict, offsetTracker) { compileDict(dict, offsetTracker) {
let out = []; const out = [];
// The dictionary keys must be in a certain order. // The dictionary keys must be in a certain order.
const order = dict.order; const order = dict.order;
for (let i = 0; i < order.length; ++i) { for (let i = 0; i < order.length; ++i) {
@ -1708,7 +1708,7 @@ class CFFCompiler {
switch (type) { switch (type) {
case "num": case "num":
case "sid": case "sid":
out = out.concat(this.encodeNumber(value)); out.push(...this.encodeNumber(value));
break; break;
case "offset": case "offset":
// For offsets we just insert a 32bit integer so we don't have to // For offsets we just insert a 32bit integer so we don't have to
@ -1720,20 +1720,20 @@ class CFFCompiler {
if (!offsetTracker.isTracking(name)) { if (!offsetTracker.isTracking(name)) {
offsetTracker.track(name, out.length); offsetTracker.track(name, out.length);
} }
out = out.concat([0x1d, 0, 0, 0, 0]); out.push(0x1d, 0, 0, 0, 0);
break; break;
case "array": case "array":
case "delta": case "delta":
out = out.concat(this.encodeNumber(value)); out.push(...this.encodeNumber(value));
for (let k = 1, kk = values.length; k < kk; ++k) { for (let k = 1, kk = values.length; k < kk; ++k) {
out = out.concat(this.encodeNumber(values[k])); out.push(...this.encodeNumber(values[k]));
} }
break; break;
default: default:
throw new FormatError(`Unknown data type of ${type}`); throw new FormatError(`Unknown data type of ${type}`);
} }
} }
out = out.concat(dict.opcodes[key]); out.push(...dict.opcodes[key]);
} }
return out; return out;
} }

View File

@ -1663,13 +1663,13 @@ class SimpleSegmentVisitor {
this.symbols = symbols = {}; this.symbols = symbols = {};
} }
let inputSymbols = []; const inputSymbols = [];
for (let i = 0, ii = referredSegments.length; i < ii; i++) { for (const referredSegment of referredSegments) {
const referredSymbols = symbols[referredSegments[i]]; const referredSymbols = symbols[referredSegment];
// referredSymbols is undefined when we have a reference to a Tables // referredSymbols is undefined when we have a reference to a Tables
// segment instead of a SymbolDictionary. // segment instead of a SymbolDictionary.
if (referredSymbols) { if (referredSymbols) {
inputSymbols = inputSymbols.concat(referredSymbols); inputSymbols.push(...referredSymbols);
} }
} }
@ -1696,13 +1696,13 @@ class SimpleSegmentVisitor {
// Combines exported symbols from all referred segments // Combines exported symbols from all referred segments
const symbols = this.symbols; const symbols = this.symbols;
let inputSymbols = []; const inputSymbols = [];
for (let i = 0, ii = referredSegments.length; i < ii; i++) { for (const referredSegment of referredSegments) {
const referredSymbols = symbols[referredSegments[i]]; const referredSymbols = symbols[referredSegment];
// referredSymbols is undefined when we have a reference to a Tables // referredSymbols is undefined when we have a reference to a Tables
// segment instead of a SymbolDictionary. // segment instead of a SymbolDictionary.
if (referredSymbols) { if (referredSymbols) {
inputSymbols = inputSymbols.concat(referredSymbols); inputSymbols.push(...referredSymbols);
} }
} }
const symbolCodeLength = log2(inputSymbols.length); const symbolCodeLength = log2(inputSymbols.length);

View File

@ -547,10 +547,7 @@ function expandBoundsLTR(width, bounds) {
} }
} }
Array.prototype.splice.apply( Array.prototype.splice.apply(horizon, [i, j - i + 1, ...changedHorizon]);
horizon,
[i, j - i + 1].concat(changedHorizon)
);
} }
// Set new x2 for all unset boundaries. // Set new x2 for all unset boundaries.