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