From 1d05c45765dc939aa7838862746057fb2f82707b Mon Sep 17 00:00:00 2001 From: Anatoli Papirovski Date: Tue, 1 May 2018 14:22:39 +0200 Subject: [PATCH 1/3] util: improve spliceOne perf Do less variable allocations and reassignments inside spliceOne since it's relied on by some performance sensitive code. confidence improvement util/splice.js size=10 n=10000000 ** 2.95 % util/splice.js size=100 n=10000000 *** 10.68 % util/splice.js size=500 n=10000000 *** 11.26 % --- benchmark/util/splice-one.js | 22 ++++++++++++++++++++++ lib/internal/util.js | 7 ++++--- 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 benchmark/util/splice-one.js diff --git a/benchmark/util/splice-one.js b/benchmark/util/splice-one.js new file mode 100644 index 00000000000000..2c53a812ba6876 --- /dev/null +++ b/benchmark/util/splice-one.js @@ -0,0 +1,22 @@ +'use strict'; + +const common = require('../common'); + +const bench = common.createBenchmark(main, { + n: [1e7], + size: [10, 100, 500], +}, { flags: ['--expose-internals'] }); + +function main({ n, size, type }) { + const { spliceOne } = require('internal/util'); + const arr = new Array(size); + arr.fill(''); + const pos = Math.floor(size / 2); + + bench.start(); + for (var i = 0; i < n; i++) { + spliceOne(arr, pos); + arr.push(''); + } + bench.end(n); +} diff --git a/lib/internal/util.js b/lib/internal/util.js index 071563a737815b..7d4f6fa88c3419 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -322,10 +322,11 @@ function join(output, separator) { return str; } -// About 1.5x faster than the two-arg version of Array#splice(). +// Depending on the size of the array, this is anywhere between 1.5-10x +// faster than the two-arg version of Array#splice() function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) - list[i] = list[k]; + for (; index + 1 < list.length; index++) + list[index] = list[index + 1]; list.pop(); } From d770149272fd34979f5ee08ea34e47214e8e76ff Mon Sep 17 00:00:00 2001 From: Anatoli Papirovski Date: Tue, 1 May 2018 14:48:50 +0200 Subject: [PATCH 2/3] fixup: address nit --- lib/internal/util.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/util.js b/lib/internal/util.js index 7d4f6fa88c3419..07515e2e090daa 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -322,8 +322,8 @@ function join(output, separator) { return str; } -// Depending on the size of the array, this is anywhere between 1.5-10x -// faster than the two-arg version of Array#splice() +// As of V8 6.6, depending on the size of the array, this is anywhere +// between 1.5-10x faster than the two-arg version of Array#splice() function spliceOne(list, index) { for (; index + 1 < list.length; index++) list[index] = list[index + 1]; From 14ed2f2a5eea3320656133c8b162fbe9f86ba0fc Mon Sep 17 00:00:00 2001 From: Anatoli Papirovski Date: Tue, 1 May 2018 15:09:24 +0200 Subject: [PATCH 3/3] fixup: implement feedback --- benchmark/util/splice-one.js | 17 ++++++++++++++--- test/parallel/test-benchmark-util.js | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/benchmark/util/splice-one.js b/benchmark/util/splice-one.js index 2c53a812ba6876..5c2a39f6d72a11 100644 --- a/benchmark/util/splice-one.js +++ b/benchmark/util/splice-one.js @@ -4,18 +4,29 @@ const common = require('../common'); const bench = common.createBenchmark(main, { n: [1e7], + pos: ['start', 'middle', 'end'], size: [10, 100, 500], }, { flags: ['--expose-internals'] }); -function main({ n, size, type }) { +function main({ n, pos, size }) { const { spliceOne } = require('internal/util'); const arr = new Array(size); arr.fill(''); - const pos = Math.floor(size / 2); + let index; + switch (pos) { + case 'end': + index = size - 1; + break; + case 'middle': + index = Math.floor(size / 2); + break; + default: // start + index = 0; + } bench.start(); for (var i = 0; i < n; i++) { - spliceOne(arr, pos); + spliceOne(arr, index); arr.push(''); } bench.end(n); diff --git a/test/parallel/test-benchmark-util.js b/test/parallel/test-benchmark-util.js index 9a6ae370b7d312..838e51daac26b4 100644 --- a/test/parallel/test-benchmark-util.js +++ b/test/parallel/test-benchmark-util.js @@ -10,6 +10,8 @@ runBenchmark('util', 'method=Array', 'n=1', 'option=none', + 'pos=start', + 'size=1', 'type=', 'version=native'], { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 });