Add JSPerf tests for more 2nd-order Array builtins

Every, Some, Reduce, ReduceRight. Added a test that should improve
when TurboFan inlines these builtins. Updated Map and Filter tests
to include a TurboFan inline test.

Bug: v8:2229
Change-Id: Ie84d414fdcccea23c734caca55a3344f9442547f
Reviewed-on: https://chromium-review.googlesource.com/558935
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46395}
This commit is contained in:
Mike Stanton 2017-07-04 10:33:39 +02:00 committed by Commit Bot
parent 3a243d3aef
commit aa5852a294
8 changed files with 348 additions and 4 deletions

View File

@ -0,0 +1,69 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// 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
// optimizations.
function RunOptFastEvery(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.every((v, i, a) => multiple === 3);
}
// Don't optimize because I want to optimize RunOptFastMap with a parameter
// to be used in the callback.
%NeverOptimizeFunction(OptFastEvery);
function OptFastEvery() { RunOptFastEvery(3); }
function SmiEverySetup() {
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = i;
func = (value, index, object) => { return value != 34343; };
}
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'; };
}

View File

@ -14,9 +14,12 @@ benchy('DoubleFilter', DoubleFilter, DoubleFilterSetup);
benchy('SmiFilter', SmiFilter, SmiFilterSetup);
benchy('FastFilter', FastFilter, FastFilterSetup);
benchy('ObjectFilter', GenericFilter, ObjectFilterSetup);
benchy('OptFastFilter', OptFastFilter, FastFilterSetup);
var array;
var func;
// 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;
@ -33,6 +36,23 @@ 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);
}

View File

@ -14,9 +14,12 @@ benchy('DoubleMap', DoubleMap, DoubleMapSetup);
benchy('SmiMap', SmiMap, SmiMapSetup);
benchy('FastMap', FastMap, FastMapSetup);
benchy('ObjectMap', GenericMap, ObjectMapSetup);
benchy('OptFastMap', OptFastMap, FastMapSetup);
var array;
var func;
// 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;
@ -33,6 +36,22 @@ 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() {
let index = -1
const length = array == null ? 0 : array.length

View File

@ -0,0 +1,69 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// 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
// optimizations.
function RunOptFastReduceRight(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.reduceRight((p, v, i, a) => p + multiple);
}
// Don't optimize because I want to optimize RunOptFastMap with a parameter
// to be used in the callback.
%NeverOptimizeFunction(OptFastReduceRight);
function OptFastReduceRight() { RunOptFastReduceRight(3); }
function SmiReduceRightSetup() {
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = i;
func = (prev, value, index, object) => { return prev + 1; };
}
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; };
}

View File

@ -0,0 +1,69 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// 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
// optimizations.
function RunOptFastReduce(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.reduce((p, v, i, a) => p + multiple);
}
// Don't optimize because I want to optimize RunOptFastMap with a parameter
// to be used in the callback.
%NeverOptimizeFunction(OptFastReduce);
function OptFastReduce() { RunOptFastReduce(3); }
function SmiReduceSetup() {
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = i;
func = (prev, value, index, object) => { return prev + 1; };
}
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; };
}

View File

@ -7,6 +7,10 @@ load('../base.js');
load('filter.js');
load('map.js');
load('every.js');
load('some.js');
load('reduce.js');
load('reduce-right.js');
var success = true;

View File

@ -0,0 +1,69 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// 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
// optimizations.
function RunOptFastSome(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.some((v, i, a) => multiple !== 3);
}
// Don't optimize because I want to optimize RunOptFastMap with a parameter
// to be used in the callback.
%NeverOptimizeFunction(OptFastSome);
function OptFastSome() { RunOptFastSome(3); }
function SmiSomeSetup() {
array = new Array();
for (var i = 0; i < array_size; i++) array[i] = i;
func = (value, index, object) => { return value === 34343; };
}
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'; };
}

View File

@ -313,7 +313,10 @@
"path": ["Array"],
"main": "run.js",
"resources": [
"filter.js", "map.js"
"filter.js", "map.js", "every.js", "some.js", "reduce.js", "reduce-right.js"
],
"flags": [
"--allow-natives-syntax"
],
"results_regexp": "^%s\\-Array\\(Score\\): (.+)$",
"tests": [
@ -322,11 +325,33 @@
{"name": "SmiFilter"},
{"name": "FastFilter"},
{"name": "ObjectFilter"},
{"name": "OptFastFilter"},
{"name": "NaiveMapReplacement"},
{"name": "DoubleMap"},
{"name": "SmiMap"},
{"name": "FastMap"},
{"name": "ObjectMap"}
{"name": "ObjectMap"},
{"name": "OptFastMap"},
{"name": "DoubleEvery"},
{"name": "SmiEvery"},
{"name": "FastEvery"},
{"name": "ObjectEvery"},
{"name": "OptFastEvery"},
{"name": "DoubleSome"},
{"name": "SmiSome"},
{"name": "FastSome"},
{"name": "ObjectSome"},
{"name": "OptFastSome"},
{"name": "DoubleReduce"},
{"name": "SmiReduce"},
{"name": "FastReduce"},
{"name": "ObjectReduce"},
{"name": "OptFastReduce"},
{"name": "DoubleReduceRight"},
{"name": "SmiReduceRight"},
{"name": "FastReduceRight"},
{"name": "ObjectReduceRight"},
{"name": "OptFastReduceRight"}
]
},
{