Commit a0ab7d45 authored by Mike Stanton's avatar Mike Stanton Committed by Commit Bot

[JSPerfTests] Refactoring in Array 2nd-order builtin tests

The (numbing) repetition in these tests were leading to errors when
writing new tests. Now a function DefineHigherOrderTests() can be
used to succinctly describe a test on (mostly) a single line.

Change-Id: I70d65ffd784a17bbf0b9ca2de477135c5d901794
Reviewed-on: https://chromium-review.googlesource.com/864144
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50590}
parent c5059623
// Copyright 2017 the V8 project authors. All rights reserved. // Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('DoubleEvery', DoubleEvery, DoubleEverySetup);
benchy('SmiEvery', SmiEvery, SmiEverySetup);
benchy('FastEvery', FastEvery, FastEverySetup);
benchy('OptFastEvery', OptFastEvery, FastEverySetup);
var array;
// Initialize func variable to ensure the first test doesn't benefit from
// global object property tracking.
var func = 0;
var this_arg;
var result;
var array_size = 100;
// Although these functions have the same code, they are separated for
// clean IC feedback.
function DoubleEvery() {
result = array.every(func, this_arg);
}
function SmiEvery() {
result = array.every(func, this_arg);
}
function FastEvery() {
result = array.every(func, this_arg);
}
// Make sure we inline the callback, pick up all possible TurboFan // Make sure we inline the callback, pick up all possible TurboFan
// optimizations. // optimizations.
...@@ -50,20 +19,12 @@ function RunOptFastEvery(multiple) { ...@@ -50,20 +19,12 @@ function RunOptFastEvery(multiple) {
%NeverOptimizeFunction(OptFastEvery); %NeverOptimizeFunction(OptFastEvery);
function OptFastEvery() { RunOptFastEvery(3); } function OptFastEvery() { RunOptFastEvery(3); }
function SmiEverySetup() { DefineHigherOrderTests([
array = new Array(); // name, test function, setup function, user callback
for (var i = 0; i < array_size; i++) array[i] = i; "DoubleEvery", mc("every"), DoubleSetup, v => v > 0.0,
func = (value, index, object) => { return value != 34343; }; "SmiEvery", mc("every"), SmiSetup, v => v != 34343,
} "FastEvery", mc("every"), FastSetup, v => v !== 'hi',
"OptFastEvery", OptFastEvery, FastSetup, v => true,
function DoubleEverySetup() { ]);
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = (i + 0.5);
func = (value, index, object) => { return value > 0.0; };
}
function FastEverySetup() { })();
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = 'value ' + i;
func = (value, index, object) => { return value !== 'hi'; };
}
// Copyright 2017 the V8 project authors. All rights reserved. // Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('NaiveFilterReplacement', NaiveFilter, NaiveFilterSetup);
benchy('DoubleFilter', DoubleFilter, DoubleFilterSetup);
benchy('SmiFilter', SmiFilter, SmiFilterSetup);
benchy('FastFilter', FastFilter, FastFilterSetup);
benchy('GenericFilter', GenericFilter, ObjectFilterSetup);
benchy('OptFastFilter', OptFastFilter, FastFilterSetup);
var array;
// Initialize func variable to ensure the first test doesn't benefit from
// global object property tracking.
var func = 0;
var this_arg;
var result;
var array_size = 100;
// Although these functions have the same code, they are separated for
// clean IC feedback.
function DoubleFilter() {
result = array.filter(func, this_arg);
}
function SmiFilter() {
result = array.filter(func, this_arg);
}
function FastFilter() {
result = array.filter(func, this_arg);
}
// Make sure we inline the callback, pick up all possible TurboFan
// optimizations.
function RunOptFastFilter(multiple) {
// Use of variable multiple in the callback function forces
// context creation without escape analysis.
//
// Also, the arrow function requires inlining based on
// SharedFunctionInfo.
result = array.filter((v, i, a) => multiple === 3);
}
// Don't optimize because I want to optimize RunOptFastMap with a parameter
// to be used in the callback.
%NeverOptimizeFunction(OptFastFilter);
function OptFastFilter() { RunOptFastFilter(3); }
function GenericFilter() {
result = Array.prototype.filter.call(array, func, this_arg);
}
// From the lodash implementation. // From the lodash implementation.
function NaiveFilter() { function NaiveFilter() {
...@@ -76,37 +22,38 @@ function NaiveFilter() { ...@@ -76,37 +22,38 @@ function NaiveFilter() {
function NaiveFilterSetup() { function NaiveFilterSetup() {
// Prime NaiveFilter with polymorphic cases. // Prime NaiveFilter with polymorphic cases.
array = [1, 2, 3]; array = [1, 2, 3];
func = ()=>true;
NaiveFilter(); NaiveFilter();
NaiveFilter(); NaiveFilter();
array = [3.4]; NaiveFilter(); array = [3.4]; NaiveFilter();
array = new Array(10); array[0] = 'hello'; NaiveFilter(); array = new Array(10); array[0] = 'hello'; NaiveFilter();
SmiFilterSetup(); SmiSetup();
delete array[1]; delete array[1];
} }
function SmiFilterSetup() { // Make sure we inline the callback, pick up all possible TurboFan
array = new Array(); // optimizations.
for (var i = 0; i < array_size; i++) array[i] = i; function RunOptFastFilter(multiple) {
func = (value, index, object) => { return value % 2 === 0; }; // Use of variable multiple in the callback function forces
} // context creation without escape analysis.
//
function DoubleFilterSetup() { // Also, the arrow function requires inlining based on
array = new Array(); // SharedFunctionInfo.
for (var i = 0; i < array_size; i++) array[i] = (i + 0.5); result = array.filter((v, i, a) => multiple === 3);
func = (value, index, object) => { return Math.floor(value) % 2 === 0; };
} }
function FastFilterSetup() { // Don't optimize because I want to optimize RunOptFastMap with a parameter
array = new Array(); // to be used in the callback.
for (var i = 0; i < array_size; i++) array[i] = 'value ' + i; %NeverOptimizeFunction(OptFastFilter);
func = (value, index, object) => { return index % 2 === 0; }; function OptFastFilter() { RunOptFastFilter(3); }
}
function ObjectFilterSetup() { DefineHigherOrderTests([
array = { length: array_size }; // name, test function, setup function, user callback
for (var i = 0; i < array_size; i++) { "NaiveFilterReplacement", NaiveFilter, NaiveFilterSetup, v => true,
array[i] = i; "DoubleFilter", mc("filter"), DoubleSetup, v => Math.floor(v) % 2 === 0,
} "SmiFilter", mc("filter"), SmiSetup, v => v % 2 === 0,
func = (value, index, object) => { return index % 2 === 0; }; "FastFilter", mc("filter"), FastSetup, (_, i) => i % 2 === 0,
} "GenericFilter", mc("filter", true), ObjectSetup, (_, i) => i % 2 === 0,
"OptFastFilter", OptFastFilter, FastSetup, undefined
]);
})();
...@@ -3,40 +3,6 @@ ...@@ -3,40 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
(() => { (() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('NaiveFindIndexReplacement', Naive, NaiveSetup);
benchy('DoubleFindIndex', Double, DoubleSetup);
benchy('SmiFindIndex', Smi, SmiSetup);
benchy('FastFindIndex', Fast, FastSetup);
benchy('GenericFindIndex', Generic, ObjectSetup);
benchy('OptFastFindIndex', OptFast, FastSetup);
let array;
// Initialize func variable to ensure the first test doesn't benefit from
// global object property tracking.
let func = 0;
let result;
const array_size = 100;
const max_index = array_size - 1;
// Although these functions have the same code, they are separated for
// clean IC feedback.
function Double() {
result = array.findIndex(func);
}
function Smi() {
result = array.findIndex(func);
}
function Fast() {
result = array.findIndex(func);
}
// Make sure we inline the callback, pick up all possible TurboFan // Make sure we inline the callback, pick up all possible TurboFan
// optimizations. // optimizations.
function RunOptFast(multiple) { function RunOptFast(multiple) {
...@@ -66,14 +32,9 @@ function Naive() { ...@@ -66,14 +32,9 @@ function Naive() {
} }
} }
function Generic() {
result = Array.prototype.findIndex.call(array, func);
}
function NaiveSetup() { function NaiveSetup() {
// Prime Naive with polymorphic cases. // Prime Naive with polymorphic cases.
array = [1, 2, 3]; array = [1, 2, 3];
func = (v, i, a) => v === max_index;
Naive(); Naive();
Naive(); Naive();
array = [3.4]; Naive(); array = [3.4]; Naive();
...@@ -82,27 +43,14 @@ function NaiveSetup() { ...@@ -82,27 +43,14 @@ function NaiveSetup() {
delete array[1]; delete array[1];
} }
function SmiSetup() { DefineHigherOrderTests([
array = Array.from({ length: array_size }, (_, i) => i); // name, test function, setup function, user callback
func = (value, index, object) => value === max_index; "NaiveFindIndexReplacement", Naive, NaiveSetup, v => v === max_index,
} "DoubleFindIndex", mc("findIndex"), DoubleSetup, v => v === max_index + 0.5,
"SmiFindIndex", mc("findIndex"), SmiSetup, v => v === max_index,
function DoubleSetup() { "FastFindIndex", mc("findIndex"), FastSetup, v => v === `value ${max_index}`,
array = Array.from({ length: array_size }, (_, i) => i + 0.5); "GenericFindIndex", mc("findIndex", true), ObjectSetup, v => v === max_index,
func = (value, index, object) => value === max_index + 0.5; "OptFastFindIndex", OptFast, FastSetup, undefined
} ]);
function FastSetup() {
array = Array.from({ length: array_size }, (_, i) => `value ${i}`);
func = (value, index, object) => value === `value ${max_index}`;
}
function ObjectSetup() {
array = { length: array_size };
for (let i = 0; i < array_size; i++) {
array[i] = i;
}
func = (value, index, object) => value === max_index;
}
})(); })();
...@@ -3,40 +3,6 @@ ...@@ -3,40 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
(() => { (() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('NaiveFindReplacement', Naive, NaiveSetup);
benchy('DoubleFind', Double, DoubleSetup);
benchy('SmiFind', Smi, SmiSetup);
benchy('FastFind', Fast, FastSetup);
benchy('GenericFind', Generic, ObjectSetup);
benchy('OptFastFind', OptFast, FastSetup);
let array;
// Initialize func variable to ensure the first test doesn't benefit from
// global object property tracking.
let func = 0;
let result;
const array_size = 100;
const max_index = array_size - 1;
// Although these functions have the same code, they are separated for
// clean IC feedback.
function Double() {
result = array.find(func);
}
function Smi() {
result = array.find(func);
}
function Fast() {
result = array.find(func);
}
// Make sure we inline the callback, pick up all possible TurboFan // Make sure we inline the callback, pick up all possible TurboFan
// optimizations. // optimizations.
function RunOptFast(multiple) { function RunOptFast(multiple) {
...@@ -66,14 +32,9 @@ function Naive() { ...@@ -66,14 +32,9 @@ function Naive() {
} }
} }
function Generic() {
result = Array.prototype.find.call(array, func);
}
function NaiveSetup() { function NaiveSetup() {
// Prime Naive with polymorphic cases. // Prime Naive with polymorphic cases.
array = [1, 2, 3]; array = [1, 2, 3];
func = (v, i, a) => v === max_index;
Naive(); Naive();
Naive(); Naive();
array = [3.4]; Naive(); array = [3.4]; Naive();
...@@ -82,27 +43,14 @@ function NaiveSetup() { ...@@ -82,27 +43,14 @@ function NaiveSetup() {
delete array[1]; delete array[1];
} }
function SmiSetup() { DefineHigherOrderTests([
array = Array.from({ length: array_size }, (_, i) => i); // name, test function, setup function, user callback
func = (value, index, object) => value === max_index; "NaiveFindReplacement", Naive, NaiveSetup, v => v === max_index,
} "DoubleFind", mc("find"), DoubleSetup, v => v === max_index + 0.5,
"SmiFind", mc("find"), SmiSetup, v => v === max_index,
function DoubleSetup() { "FastFind", mc("find"), FastSetup, v => v === `value ${max_index}`,
array = Array.from({ length: array_size }, (_, i) => i + 0.5); "GenericFind", mc("find", true), ObjectSetup, v => v === max_index,
func = (value, index, object) => value === max_index + 0.5; "OptFastFind", OptFast, FastSetup, undefined
} ]);
function FastSetup() {
array = Array.from({ length: array_size }, (_, i) => `value ${i}`);
func = (value, index, object) => value === `value ${max_index}`;
}
function ObjectSetup() {
array = { length: array_size };
for (let i = 0; i < array_size; i++) {
array[i] = i;
}
func = (value, index, object) => value === max_index;
}
})(); })();
// Copyright 2017 the V8 project authors. All rights reserved. // Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('SmiJoin', SmiJoin, SmiJoinSetup);
benchy('StringJoin', StringJoin, StringJoinSetup);
benchy('SparseSmiJoin', SparseSmiJoin, SparseSmiJoinSetup);
benchy('SparseStringJoin', SparseStringJoin, SparseStringJoinSetup);
var array; var array;
var result; var result;
var array_size = 1000; var array_size = 1000;
function make_join() {
// Although these functions have the same code, they are separated for return new Function('result = array.join();');
// clean IC feedback.
function SmiJoin() {
result = array.join();
}
function StringJoin() {
result = array.join();
}
function SparseSmiJoin() {
result = array.join();
}
function SparseStringJoin() {
result = array.join();
} }
benchy('SmiJoin', make_join(), SmiJoinSetup);
benchy('StringJoin', make_join(), StringJoinSetup);
benchy('SparseSmiJoin', make_join(), SparseSmiJoinSetup);
benchy('SparseStringJoin', make_join(), SparseStringJoinSetup);
function SmiJoinSetup() { function SmiJoinSetup() {
array = new Array(); array = new Array();
for (var i = 0; i < array_size; ++i) array[i] = i; for (var i = 0; i < array_size; ++i) array[i] = i;
...@@ -50,3 +32,5 @@ function SparseStringJoinSetup() { ...@@ -50,3 +32,5 @@ function SparseStringJoinSetup() {
StringJoinSetup(); StringJoinSetup();
array.length = array.length * 2; array.length = array.length * 2;
} }
})();
// Copyright 2017 the V8 project authors. All rights reserved. // Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('NaiveMapReplacement', NaiveMap, NaiveMapSetup);
benchy('DoubleMap', DoubleMap, DoubleMapSetup);
benchy('SmallSmiToDoubleMap', SmiMap, SmiToDoubleMapSetup);
benchy('SmallSmiToFastMap', SmiMap, SmiToFastMapSetup);
benchy('SmiMap', SmiMap, SmiMapSetup);
benchy('FastMap', FastMap, FastMapSetup);
benchy('GenericMap', GenericMap, ObjectMapSetup);
benchy('OptFastMap', OptFastMap, FastMapSetup);
var array;
// Initialize func variable to ensure the first test doesn't benefit from
// global object property tracking.
var func = 0;
var this_arg;
var result;
var array_size = 100;
// Although these functions have the same code, they are separated for
// clean IC feedback.
function DoubleMap() {
result = array.map(func, this_arg);
}
function SmiMap() {
result = array.map(func, this_arg);
}
function FastMap() {
result = array.map(func, this_arg);
}
// Make sure we inline the callback, pick up all possible TurboFan
// optimizations.
function RunOptFastMap(multiple) {
// Use of variable multiple in the callback function forces
// context creation without escape analysis.
//
// Also, the arrow function requires inlining based on
// SharedFunctionInfo.
result = array.map((v, i, a) => v + ' ' + multiple);
}
// Don't optimize because I want to optimize RunOptFastMap with a parameter
// to be used in the callback.
%NeverOptimizeFunction(OptFastMap);
function OptFastMap() { RunOptFastMap(3); }
function NaiveMap() { function NaiveMap() {
let index = -1 let index = -1
...@@ -66,56 +15,43 @@ function NaiveMap() { ...@@ -66,56 +15,43 @@ function NaiveMap() {
} }
function GenericMap() {
result = Array.prototype.map.call(array, func, this_arg);
}
function NaiveMapSetup() { function NaiveMapSetup() {
// Prime NaiveMap with polymorphic cases. // Prime NaiveMap with polymorphic cases.
array = [1, 2, 3]; array = [1, 2, 3];
func = (v, i, a) => v;
NaiveMap(); NaiveMap();
NaiveMap(); NaiveMap();
array = [3.4]; NaiveMap(); array = [3.4]; NaiveMap();
array = new Array(10); array[0] = 'hello'; NaiveMap(); array = new Array(10); array[0] = 'hello'; NaiveMap();
SmiMapSetup(); SmiSetup();
delete array[1]; delete array[1];
} }
function SmiMapSetup() { // Make sure we inline the callback, pick up all possible TurboFan
array = new Array(); // optimizations.
for (var i = 0; i < array_size; i++) array[i] = i; function RunOptFastMap(multiple) {
func = (value, index, object) => { return value; }; // Use of variable multiple in the callback function forces
} // context creation without escape analysis.
//
function SmiToDoubleMapSetup() { // Also, the arrow function requires inlining based on
array = new Array(); // SharedFunctionInfo.
for (var i = 0; i < 1; i++) array[i] = i; result = array.map((v, i, a) => v + ' ' + multiple);
func = (value, index, object) => { return value + 0.5; };
}
function SmiToFastMapSetup() {
array = new Array();
for (var i = 0; i < 1; i++) array[i] = i;
func = (value, index, object) => { return "hi" + value; };
}
function DoubleMapSetup() {
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = (i + 0.5);
func = (value, index, object) => { return value; };
} }
function FastMapSetup() { // Don't optimize because I want to optimize RunOptFastMap with a parameter
array = new Array(); // to be used in the callback.
for (var i = 0; i < array_size; i++) array[i] = 'value ' + i; %NeverOptimizeFunction(OptFastMap);
func = (value, index, object) => { return value; }; function OptFastMap() { RunOptFastMap(3); }
}
function ObjectMapSetup() { DefineHigherOrderTests([
array = { length: array_size }; // name, test function, setup function, user callback
for (var i = 0; i < array_size; i++) { "NaiveMapReplacement", NaiveMap, NaiveMapSetup, v => v,
array[i] = i; "SmiMap", mc("map"), SmiSetup, v => v,
} "DoubleMap", mc("map"), DoubleSetup, v => v,
func = (value, index, object) => { return value; }; "FastMap", mc("map"), FastSetup, v => v,
} "SmallSmiToDoubleMap", mc("map"), SmiSetup, v => v + 0.5,
"SmallSmiToFastMap", mc("map"), SmiSetup, v => "hi" + v,
"GenericMap", mc("map", true), ObjectSetup, v => v,
"OptFastMap", OptFastMap, FastSetup, undefined,
]);
})();
// Copyright 2018 the V8 project authors. All rights reserved. // Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('EmptyArrayOf', EmptyArrayOf, EmptyArrayOfSetup); benchy('EmptyArrayOf', EmptyArrayOf, EmptyArrayOfSetup);
benchy('SmallTransplantedArrayOf', SmallTransplantedArrayOf, benchy('SmallTransplantedArrayOf', SmallTransplantedArrayOf,
...@@ -119,3 +113,5 @@ function LargeSmiArrayOfSetup() { ...@@ -119,3 +113,5 @@ function LargeSmiArrayOfSetup() {
arg19 = 19; arg19 = 19;
arg20 = 20; arg20 = 20;
} }
})();
// Copyright 2017 the V8 project authors. All rights reserved. // Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('DoubleReduceRight', DoubleReduceRight, DoubleReduceRightSetup);
benchy('SmiReduceRight', SmiReduceRight, SmiReduceRightSetup);
benchy('FastReduceRight', FastReduceRight, FastReduceRightSetup);
benchy('OptFastReduceRight', OptFastReduceRight, FastReduceRightSetup);
var array;
// Initialize func variable to ensure the first test doesn't benefit from
// global object property tracking.
var func = 0;
var this_arg;
var result;
var array_size = 100;
// Although these functions have the same code, they are separated for
// clean IC feedback.
function DoubleReduceRight() {
result = array.reduceRight(func, this_arg);
}
function SmiReduceRight() {
result = array.reduceRight(func, this_arg);
}
function FastReduceRight() {
result = array.reduceRight(func, this_arg);
}
// Make sure we inline the callback, pick up all possible TurboFan // Make sure we inline the callback, pick up all possible TurboFan
// optimizations. // optimizations.
...@@ -50,20 +19,12 @@ function RunOptFastReduceRight(multiple) { ...@@ -50,20 +19,12 @@ function RunOptFastReduceRight(multiple) {
%NeverOptimizeFunction(OptFastReduceRight); %NeverOptimizeFunction(OptFastReduceRight);
function OptFastReduceRight() { RunOptFastReduceRight(3); } function OptFastReduceRight() { RunOptFastReduceRight(3); }
function SmiReduceRightSetup() { DefineHigherOrderTests([
array = new Array(); // name, test function, setup function, user callback
for (var i = 0; i < array_size; i++) array[i] = i; "DoubleReduceRight", mc("reduceRight"), DoubleSetup, (p, v, i, o) => p + v,
func = (prev, value, index, object) => { return prev + 1; }; "SmiReduceRight", mc("reduceRight"), SmiSetup, (p, v, i, a) => p + 1,
} "FastReduceRight", mc("reduceRight"), FastSetup, (p, v, i, a) => p + v,
"OptFastReduceRight", OptFastReduceRight, FastSetup, undefined
function DoubleReduceRightSetup() { ]);
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = (i + 0.5);
func = (prev, value, index, object) => { return prev + value; };
}
function FastReduceRightSetup() { })();
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = 'value ' + i;
func = (prev, value, index, object) => { return prev + value; };
}
// Copyright 2017 the V8 project authors. All rights reserved. // Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('DoubleReduce', DoubleReduce, DoubleReduceSetup);
benchy('SmiReduce', SmiReduce, SmiReduceSetup);
benchy('FastReduce', FastReduce, FastReduceSetup);
benchy('OptFastReduce', OptFastReduce, FastReduceSetup);
var array;
// Initialize func variable to ensure the first test doesn't benefit from
// global object property tracking.
var func = 0;
var this_arg;
var result;
var array_size = 100;
// Although these functions have the same code, they are separated for
// clean IC feedback.
function DoubleReduce() {
result = array.reduce(func, this_arg);
}
function SmiReduce() {
result = array.reduce(func, this_arg);
}
function FastReduce() {
result = array.reduce(func, this_arg);
}
// Make sure we inline the callback, pick up all possible TurboFan // Make sure we inline the callback, pick up all possible TurboFan
// optimizations. // optimizations.
...@@ -50,20 +19,12 @@ function RunOptFastReduce(multiple) { ...@@ -50,20 +19,12 @@ function RunOptFastReduce(multiple) {
%NeverOptimizeFunction(OptFastReduce); %NeverOptimizeFunction(OptFastReduce);
function OptFastReduce() { RunOptFastReduce(3); } function OptFastReduce() { RunOptFastReduce(3); }
function SmiReduceSetup() { DefineHigherOrderTests([
array = new Array(); // name, test function, setup function, user callback
for (var i = 0; i < array_size; i++) array[i] = i; "DoubleReduce", mc("reduce"), DoubleSetup, (p, v, i, o) => p + v,
func = (prev, value, index, object) => { return prev + 1; }; "SmiReduce", mc("reduce"), SmiSetup, (p, v, i, a) => p + 1,
} "FastReduce", mc("reduce"), FastSetup, (p, v, i, a) => p + v,
"OptFastReduce", OptFastReduce, FastSetup, undefined
function DoubleReduceSetup() { ]);
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = (i + 0.5);
func = (prev, value, index, object) => { return prev + value; };
}
function FastReduceSetup() { })();
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = 'value ' + i;
func = (prev, value, index, object) => { return prev + value; };
}
...@@ -2,21 +2,86 @@ ...@@ -2,21 +2,86 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
load('../base.js'); load('../base.js');
let array;
// Initialize func variable to ensure the first test doesn't benefit from
// global object property tracking.
let func = 0;
let this_arg;
let result;
const array_size = 100;
const max_index = array_size - 1;
// mc stands for "Make Closure," it's a handy function to get a fresh
// closure unpolluted by IC feedback for a 2nd-order array builtin
// test.
function mc(name, generic = false) {
if (generic) {
return new Function(
`result = Array.prototype.${name}.call(array, func, this_arg);`);
}
return new Function(`result = array.${name}(func, this_arg);`);
}
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
function SmiSetup() {
array = Array.from({ length: array_size }, (_, i) => i);
}
function DoubleSetup() {
array = Array.from({ length: array_size }, (_, i) => i + 0.5);
}
function FastSetup() {
array = Array.from({ length: array_size }, (_, i) => `value ${i}`);
}
function ObjectSetup() {
array = { length: array_size };
for (var i = 0; i < array_size; i++) {
array[i] = i;
}
}
function DefineHigherOrderTests(tests) {
let i = 0;
while (i < tests.length) {
const name = tests[i++];
const testFunc = tests[i++];
const setupFunc = tests[i++];
const callback = tests[i++];
let setupFuncWrapper = () => {
func = callback;
this_arg = undefined;
setupFunc();
};
benchy(name, testFunc, setupFuncWrapper);
}
}
// Higher-order Array builtins.
load('filter.js'); load('filter.js');
load('map.js'); load('map.js');
load('every.js'); load('every.js');
load('join.js');
load('some.js'); load('some.js');
load('reduce.js'); load('reduce.js');
load('reduce-right.js'); load('reduce-right.js');
load('to-string.js');
load('find.js'); load('find.js');
load('find-index.js'); load('find-index.js');
load('of.js'); load('of.js');
// Other Array builtins.
load('join.js');
load('to-string.js');
var success = true; var success = true;
function PrintResult(name, result) { function PrintResult(name, result) {
......
// Copyright 2017 the V8 project authors. All rights reserved. // Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(() => {
function benchy(name, test, testSetup) {
new BenchmarkSuite(name, [1000],
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
}
benchy('DoubleSome', DoubleSome, DoubleSomeSetup);
benchy('SmiSome', SmiSome, SmiSomeSetup);
benchy('FastSome', FastSome, FastSomeSetup);
benchy('OptFastSome', OptFastSome, FastSomeSetup);
var array;
// Initialize func variable to ensure the first test doesn't benefit from
// global object property tracking.
var func = 0;
var this_arg;
var result;
var array_size = 100;
// Although these functions have the same code, they are separated for
// clean IC feedback.
function DoubleSome() {
result = array.some(func, this_arg);
}
function SmiSome() {
result = array.some(func, this_arg);
}
function FastSome() {
result = array.some(func, this_arg);
}
// Make sure we inline the callback, pick up all possible TurboFan // Make sure we inline the callback, pick up all possible TurboFan
// optimizations. // optimizations.
...@@ -50,20 +19,12 @@ function RunOptFastSome(multiple) { ...@@ -50,20 +19,12 @@ function RunOptFastSome(multiple) {
%NeverOptimizeFunction(OptFastSome); %NeverOptimizeFunction(OptFastSome);
function OptFastSome() { RunOptFastSome(3); } function OptFastSome() { RunOptFastSome(3); }
function SmiSomeSetup() { DefineHigherOrderTests([
array = new Array(); // name, test function, setup function, user callback
for (var i = 0; i < array_size; i++) array[i] = i; "DoubleSome", mc("some"), DoubleSetup, v => v < 0.0,
func = (value, index, object) => { return value === 34343; }; "SmiSome", mc("some"), SmiSetup, v => v === 34343,
} "FastSome", mc("some"), FastSetup, v => v === 'hi',
"OptFastSome", OptFastSome, FastSetup, undefined
function DoubleSomeSetup() { ]);
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = (i + 0.5);
func = (value, index, object) => { return value < 0.0; };
}
function FastSomeSetup() { })();
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = 'value ' + i;
func = (value, index, object) => { return value === 'hi'; };
}
// Copyright 2017 the V8 project authors. All rights reserved. // Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
(() => {
function benchy(name, test, testSetup) { function make_tostring() {
new BenchmarkSuite(name, [1000], return new Function("result = array.toString();");
[
new Benchmark(name, false, false, 0, test, testSetup, ()=>{})
]);
} }
benchy('SmiToString', SmiToString, SmiToStringSetup); benchy('SmiToString', make_tostring(), SmiToStringSetup);
benchy('StringToString', StringToString, StringToStringSetup); benchy('StringToString', make_tostring(), StringToStringSetup);
benchy('SparseSmiToString', SparseSmiToString, SparseSmiToStringSetup); benchy('SparseSmiToString', make_tostring(), SparseSmiToStringSetup);
benchy('SparseStringToString', SparseStringToString, SparseStringToStringSetup); benchy('SparseStringToString', make_tostring(), SparseStringToStringSetup);
var array; var array;
var result; var result;
var array_size = 1000; var array_size = 1000;
// Although these functions have the same code, they are separated for
// clean IC feedback.
function SmiToString() {
result = array.toString();
}
function StringToString() {
result = array.toString();
}
function SparseSmiToString() {
result = array.toString();
}
function SparseStringToString() {
result = array.toString();
}
function SmiToStringSetup() { function SmiToStringSetup() {
array = new Array(); array = new Array();
for (var i = 0; i < array_size; ++i) array[i] = i; for (var i = 0; i < array_size; ++i) array[i] = i;
} }
function StringToStringSetup() { function StringToStringSetup() {
array = new Array(); array = new Array();
for (var i = 0; i < array_size; ++i) array[i] = `Item no. ${i}`; for (var i = 0; i < array_size; ++i) array[i] = `Item no. ${i}`;
} }
function SparseSmiToStringSetup() { function SparseSmiToStringSetup() {
SmiToStringSetup(); SmiToStringSetup();
array.length = array.length * 2; array.length = array.length * 2;
} }
function SparseStringToStringSetup() { function SparseStringToStringSetup() {
StringToStringSetup(); StringToStringSetup();
array.length = array.length * 2; array.length = array.length * 2;
} }
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment