[js-perf-test] Fewer number-to-string conversions in Array benchmarks

Some of the Array benchmarks were unintentionally spending a lot of
time on Number-to-String conversions. This patch avoids that, by
computing the dynamically-created strings only once.

Bug: chromium:1240981
Change-Id: If10826813d555398b45c22c958dee27e17f35d3c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3106747
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76387}
This commit is contained in:
Jakob Kummerow 2021-08-19 12:45:26 +02:00 committed by V8 LUCI CQ
parent 66a85b8e57
commit 6dd3fbe40f
7 changed files with 30 additions and 28 deletions

View File

@ -5,19 +5,19 @@
// Make sure we inline the callback, pick up all possible TurboFan
// optimizations.
function RunOptFast(multiple) {
// Use of variable multiple in the callback function forces
function RunOptFast(value) {
// Use of variable {value} in the callback function forces
// context creation without escape analysis.
//
// Also, the arrow function requires inlining based on
// SharedFunctionInfo.
result = array.findIndex((v, i, a) => v === `value ${multiple}`);
result = array.findIndex((v, i, a) => v === value);
}
// Don't optimize because I want to optimize RunOptFast with a parameter
// to be used in the callback.
%NeverOptimizeFunction(OptFast);
function OptFast() { RunOptFast(max_index); }
function OptFast() { RunOptFast(max_index_value); }
function side_effect(a) { return a; }
%NeverOptimizeFunction(side_effect);
@ -59,7 +59,7 @@ DefineHigherOrderTests([
['SmiFindIndex', newClosure('findIndex'), SmiSetup, v => v === max_index],
[
'FastFindIndex', newClosure('findIndex'), FastSetup,
v => v === `value ${max_index}`
v => v === max_index_value
],
[
'GenericFindIndex', newClosure('findIndex', true), ObjectSetup,

View File

@ -5,19 +5,19 @@
// Make sure we inline the callback, pick up all possible TurboFan
// optimizations.
function RunOptFast(multiple) {
// Use of variable multiple in the callback function forces
function RunOptFast(value) {
// Use of variable {value} in the callback function forces
// context creation without escape analysis.
//
// Also, the arrow function requires inlining based on
// SharedFunctionInfo.
result = array.find((v, i, a) => v === `value ${multiple}`);
result = array.find((v, i, a) => v === value);
}
// Don't optimize because I want to optimize RunOptFast with a parameter
// to be used in the callback.
%NeverOptimizeFunction(OptFast);
function OptFast() { RunOptFast(max_index); }
function OptFast() { RunOptFast(max_index_value); }
function side_effect(a) { return a; }
%NeverOptimizeFunction(side_effect);
@ -54,7 +54,7 @@ DefineHigherOrderTests([
['NaiveFindReplacement', Naive, NaiveSetup, v => v === max_index],
['DoubleFind', newClosure('find'), DoubleSetup, v => v === max_index + 0.5],
['SmiFind', newClosure('find'), SmiSetup, v => v === max_index],
['FastFind', newClosure('find'), FastSetup, v => v === `value ${max_index}`],
['FastFind', newClosure('find'), FastSetup, v => v === max_index_value],
['GenericFind', newClosure('find', true), ObjectSetup, v => v === max_index],
['OptFastFind', OptFast, FastSetup, undefined],
['OptUnreliableFind', OptUnreliable, FastSetup, v => v === max_index]

View File

@ -29,19 +29,19 @@ function NaiveSetup() {
// Make sure we inline the callback, pick up all possible TurboFan
// optimizations.
function RunOptFast(multiple) {
// Use of variable multiple in the callback function forces
function RunOptFast(value) {
// Use of variable {value} in the callback function forces
// context creation without escape analysis.
//
// Also, the arrow function requires inlining based on
// SharedFunctionInfo.
result = array.forEach((v, i, a) => v === `value ${multiple}`);
result = array.forEach((v, i, a) => v === value);
}
// Don't optimize because I want to optimize RunOptFast with a parameter
// to be used in the callback.
%NeverOptimizeFunction(OptFast);
function OptFast() { RunOptFast(max_index); }
function OptFast() { RunOptFast(max_index_value); }
function side_effect(a) { return a; }
%NeverOptimizeFunction(side_effect);
@ -58,7 +58,7 @@ DefineHigherOrderTests([
['SmiForEach', newClosure('forEach'), SmiSetup, v => v === max_index],
[
'FastForEach', newClosure('forEach'), FastSetup,
v => v === `value ${max_index}`
v => v === max_index_value
],
[
'GenericForEach', newClosure('forEach', true), ObjectSetup,
@ -67,7 +67,7 @@ DefineHigherOrderTests([
['OptFastForEach', OptFast, FastSetup, undefined],
[
'OptUnreliableForEach', OptUnreliable, FastSetup,
v => v === `value ${max_index}`
v => v === max_index_value
]
]);

View File

@ -27,19 +27,19 @@ function NaiveMapSetup() {
// Make sure we inline the callback, pick up all possible TurboFan
// optimizations.
function RunOptFastMap(multiple) {
// Use of variable multiple in the callback function forces
function RunOptFastMap(value) {
// Use of variable {value} 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);
result = array.map((v, i, a) => v + value);
}
// 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 OptFastMap() { RunOptFastMap(" 3"); }
function side_effect(a) { return a; }
%NeverOptimizeFunction(side_effect);

View File

@ -5,19 +5,19 @@
// Make sure we inline the callback, pick up all possible TurboFan
// optimizations.
function RunOptFastReduceRight(multiple) {
// Use of variable multiple in the callback function forces
function RunOptFastReduceRight(value) {
// Use of variable {value} 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);
result = array.reduceRight((p, v, i, a) => p + value);
}
// 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 OptFastReduceRight() { RunOptFastReduceRight("3"); }
function side_effect(a) { return a; }
%NeverOptimizeFunction(side_effect);

View File

@ -5,19 +5,19 @@
// Make sure we inline the callback, pick up all possible TurboFan
// optimizations.
function RunOptFastReduce(multiple) {
// Use of multiple variables in the callback function forces
function RunOptFastReduce(value) {
// Use of variable {value} 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);
result = array.reduce((p, v, i, a) => p + value);
}
// 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 OptFastReduce() { RunOptFastReduce("3"); }
function side_effect(a) { return a; }
%NeverOptimizeFunction(side_effect);

View File

@ -12,6 +12,8 @@ let this_arg;
let result;
const array_size = 100;
const max_index = array_size - 1;
// Matches what {FastSetup} below produces.
const max_index_value = `value ${max_index}`;
// newClosure is a handy function to get a fresh
// closure unpolluted by IC feedback for a 2nd-order array builtin