• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/*
17    This file was generated by VMB using these parameters:
18
19        Benchmarks Class:     $state_name
20        Bench Setup:          $state_setup
21        Bench Method:         $method_name -> $method_rettype
22        Parameter Set:        #$fix_id $fixture
23        Bench Full Name:      $bench_name
24        WarmUp Iterations:    $wi
25        Measure Iterations:   $mi
26        Iteration Time (sec): $it
27        Warmup Time (sec):    $wt
28        Fast Iterations:      $fi
29        GC pause (ms):        $gc (N/A)
30*/
31
32$imports;
33
34// map ets numerical types to number
35type long = number;
36type int = number;
37type short = number;
38type float = number;
39type double = number;
40type byte = number;
41
42// params
43let WI: int = $wi;
44let MI: int = $mi;
45let IT: int = $it;
46let WT: int = $wt;
47let FI: int = $fi;
48
49const MAX_LOOP_COUNT = 10_000_000_000;
50const MS2NS = 1_000_000;
51const S2MS = 1_000;
52
53class Consumer {
54    static x1: number = 0x41c64e6d;
55    static x2: number = 0xd431;
56    static x3: number = 1;
57    static boola: boolean = false;
58    static boolb: boolean = true;
59    static chara: string = 'X';
60    static charb: string = 'Y';
61    static floata: number = 24.0;
62    static floatb: number = 53.0;
63    static localObj: Object = new Object();
64    static localObjs: Object[] = [new Object()];
65    static pseudorand: number = Date.now();
66
67    static consume_boolean(boolc: boolean): void {
68        if (boolc === this.boola && boolc === this.boolb) {
69            throw new Error();
70        }
71    }
72
73    static consume_string(charc: string): void {
74        if (charc === this.chara && charc === this.charb) {
75            throw new Error();
76        }
77    }
78
79    static consume_number(floatc: number): void {
80        if (floatc === this.floata && floatc === this.floatb) {
81            throw new Error();
82        }
83    }
84
85    static consume_Object(obj: Object): void {
86        this.pseudorand = (this.pseudorand * this.x1 + this.x2);
87        if ((this.pseudorand & this.x3) === 0) {
88            this.x3 = (this.x3 << 1) + 0xad;
89            this.localObj = obj;
90        }
91    }
92
93    static consume_Objects(objs: Object[]): void {
94        this.pseudorand = (this.pseudorand * this.x1 + this.x2);
95        if ((this.pseudorand & this.x3) === 0) {
96            this.x3 = (this.x3 << 1) + 0xad;
97            this.localObjs = objs;
98        }
99    }
100}
101
102function log(msg: string): void {
103    print(msg);
104}
105
106$common;
107
108$src;
109
110let bench = new $state_name();
111$state_params;
112$state_setup;
113
114let loopCount1: number;
115let totalOps: number = 0;
116let totalMs: number = 0;
117let iter: number;
118
119function tune(): void {
120    let iterMs: number = 1 * S2MS;
121    let loopMs: number = 0;
122    let loopCount: number = 1;
123    while (loopMs < iterMs && loopCount < MAX_LOOP_COUNT) {
124        loopCount = loopCount * 2;
125        let start: number = Date.now();
126        for (let i: number = 0; i < loopCount; i++) {
127            $method_call;
128        }
129        loopMs = Date.now() - start;
130    }
131    loopCount1 = loopCount * iterMs / loopMs >> 0;
132    if (loopCount1 === 0) {
133        loopCount1++;
134    }
135    log('Tuning: ' + loopCount + ' ops, ' +
136        loopMs * MS2NS / loopCount + ' ns/op => ' +
137        loopCount1 + ' reps');
138}
139
140function runIters(phase: string, count: number, time: number): void {
141    let iterMs = time * S2MS;
142    totalOps = 0;
143    totalMs = 1 / Infinity; // make sure zero is encoded as double to avoid de-optimization on overflow later
144    for (let k = 0; k < count; k++, iter++) {
145        let ops = 0;
146        let elapsedMs = 0;
147        let start = Date.now();
148        while (elapsedMs < iterMs) {
149            for (let i = 0; i < loopCount1; i++) {
150                $method_call;
151            }
152            elapsedMs = Date.now() - start;
153            ops += loopCount1;
154        }
155        totalOps += ops;
156        totalMs += elapsedMs;
157        log(phase + ' ' + iter + ':' + ops + ' ops, ' + elapsedMs * MS2NS / ops + ' ns/op');
158    }
159}
160
161log('Startup execution started: ' + Date.now() * MS2NS);
162if (FI > 0) {
163    let start = Date.now();
164    for (let i = 0; i < FI; i++) {
165        $method_call;
166    }
167    let elapsed = Date.now() - start;
168    if (elapsed <= 0) {
169        elapsed = 1; // 0 is invalid result
170    }
171    log('Benchmark result: $bench_name ' + elapsed * MS2NS / FI);
172} else {
173    tune();
174    if (WI > 0) {
175        iter = 1;
176        // Re-entering runIters in warmup loop to allow profiler complete the method.
177        // Possible de-optimizations and recompilations is done in warmup instead of measure phase.
178        for (let wi = 0; wi < WI; ++wi) {
179            runIters('Warmup', 1, WT);
180        }
181    }
182    iter = 1;
183    let measure_iters = MI >> 0; // make sure it has int type
184    runIters('Iter', measure_iters, IT);
185    log('Benchmark result: $bench_name ' + totalMs * MS2NS / totalOps);
186}
187
188Consumer.consume_Object(bench);
189