* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any): string;
declare interface ArkTools {
timeInUs(arg: any): number;
isStableJsArray(arr: any[]): boolean;
getElementsKind(arr: any[]): number;
}
const REP_COUNT = 100_000;
function initializeDenseArray(target: any, len: number, a: number, b: number, intOnly = true) {
for (let i = 0; i < len; i++) {
target[i] = (i * a + b) % len;
if (!intOnly && i % 2 == 0) {
target[i] += i / len;
}
}
}
function initializeSparseArray(target: any, len: number, nNonHole: number, a: number, b: number, intOnly = true) {
let last = 0;
const getNextElement = () => {
const res = (last * a + b) % len;
last = res;
return res;
}
for (let i = 0; i < nNonHole; i++) {
const index = getNextElement();
let value = getNextElement();
if (!intOnly && i % 2 == 0) {
value += i / len;
}
target[index] = value;
}
}
const result = {};
function testArrayFunc(fnName: string, caseName: string, arr: number[]) {
print(`-------- Starts new test of Array.prototype.${fnName}() --------`)
print(`Is arr stable array? ${ArkTools.isStableJsArray(arr)}`);
print(`arr.length = ${arr.length}. ElementsKind of arr: ${ArkTools.getElementsKind(arr)}`);
const someObj = { x: 1, y: 2, valueOf() { return 3; } };
let start: number;
let end: number;
let endExtra: number;
start = ArkTools.timeInUs();
for (let i = 0; i < REP_COUNT; i++) {
arr[fnName](i);
}
end = ArkTools.timeInUs();
for (let i = 0; i < REP_COUNT; i++) {
arr[fnName];
i;
}
endExtra = ArkTools.timeInUs();
const durationI = result[`${fnName}.${caseName}.intIndex`] = (2 * end - start - endExtra) / 1000;
print(`\tsearchElement is integer: ${durationI.toFixed(3)} ms.`);
start = ArkTools.timeInUs();
for (let i = 0; i < REP_COUNT; i++) {
arr[fnName](1.1 * i);
}
end = ArkTools.timeInUs();
for (let i = 0; i < REP_COUNT; i++) {
arr[fnName];
1.1 * i;
}
endExtra = ArkTools.timeInUs();
const durationF = result[`${fnName}.${caseName}.doubleIndex`] = (2 * end - start - endExtra) / 1000;
print(`\tsearchElement is double: ${durationF.toFixed(3)} ms.`);
start = ArkTools.timeInUs();
for (let i = 0; i < REP_COUNT; i++) {
arr[fnName]("1");
}
end = ArkTools.timeInUs();
for (let i = 0; i < REP_COUNT; i++) {
arr[fnName];
"1";
}
endExtra = ArkTools.timeInUs();
const durationS = result[`${fnName}.${caseName}.stringIndex`] = (2 * end - start - endExtra) / 1000;
print(`\tsearchElement is string: ${durationS.toFixed(3)} ms.`);
start = ArkTools.timeInUs();
for (let i = 0; i < REP_COUNT; i++) {
arr[fnName](someObj);
}
end = ArkTools.timeInUs();
for (let i = 0; i < REP_COUNT; i++) {
arr[fnName];
someObj;
}
endExtra = ArkTools.timeInUs();
const durationO = result[`${fnName}.${caseName}.objectIndex`] = (2 * end - start - endExtra) / 1000;
print(`\tsearchElement is object: ${durationO.toFixed(3)} ms.`);
}
for (const fnName of ['includes', 'indexOf', 'lastIndexOf']) {
{
const empty = [];
testArrayFunc(fnName, 'empty', empty);
}
{
const [ARR_LENGTH, N_NOT_HOLE_ELEMENTS, GEN_A, GEN_B] = [1499, 100, 233, 1];
const arr = new Array<number>(ARR_LENGTH);
initializeSparseArray(arr, ARR_LENGTH, N_NOT_HOLE_ELEMENTS, GEN_A, GEN_B);
testArrayFunc(fnName, `sparse.len${ARR_LENGTH}.generic`, arr);
}
{
const [ARR_LENGTH, GEN_A, GEN_B] = [10007, 233, 1];
const arr = new Array<number>(ARR_LENGTH);
initializeDenseArray(arr, ARR_LENGTH, GEN_A, GEN_B);
testArrayFunc(fnName, `dense.len${ARR_LENGTH}.generic`, arr);
}
for (const intOnly of [true, false]) {
{
const [ARR_LENGTH, GEN_A, GEN_B] = [17, 5, 1];
const arr: number[] = [];
initializeDenseArray(arr, ARR_LENGTH, GEN_A, GEN_B, intOnly);
testArrayFunc(fnName, `dense.len${ARR_LENGTH}.${intOnly ? 'int' : 'number'}`, arr);
}
{
const [ARR_LENGTH, N_NOT_HOLE_ELEMENTS, GEN_A, GEN_B] = [1499, 100, 233, 1];
const arr: number[] = [];
initializeSparseArray(arr, ARR_LENGTH, N_NOT_HOLE_ELEMENTS, GEN_A, GEN_B, intOnly);
testArrayFunc(fnName, `sparse.len${ARR_LENGTH}.hole${intOnly ? 'Int' : 'Number'}`, arr);
}
{
const [ARR_LENGTH, GEN_A, GEN_B] = [10007, 233, 1];
const arr: number[] = [];
initializeDenseArray(arr, ARR_LENGTH, GEN_A, GEN_B, intOnly);
testArrayFunc(fnName, `dense.len${ARR_LENGTH}.${intOnly ? 'int' : 'number'}`, arr);
}
}
}
print(JSON.stringify(result, null, 4));