MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 162 lines 4.6 kB view raw
1const now = () => (typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now()); 2 3function readScale() { 4 if (typeof process === 'undefined' || !process || !process.argv) return 1; 5 const raw = Number(process.argv[2]); 6 return Number.isFinite(raw) && raw > 0 ? raw : 1; 7} 8 9const SCALE = readScale(); 10const REPEATS = 5; 11 12function opaque(v) { 13 return v; 14} 15 16function runCase(name, rounds, fn) { 17 // Warm up once with a smaller trip count. 18 fn(Math.max(1, (rounds / 8) | 0)); 19 20 const samples = []; 21 let out = 0; 22 for (let i = 0; i < REPEATS; i++) { 23 const t0 = now(); 24 out = fn(rounds); 25 samples.push(now() - t0); 26 } 27 28 let best = samples[0]; 29 let sum = 0; 30 for (let i = 0; i < samples.length; i++) { 31 if (samples[i] < best) best = samples[i]; 32 sum += samples[i]; 33 } 34 const avg = sum / samples.length; 35 console.log(`${name}: best ${best.toFixed(2)} ms, avg ${avg.toFixed(2)} ms`); 36 return { best, avg, out }; 37} 38 39function reportPair(title, rounds, typedFn, unknownFn) { 40 console.log(`\n== ${title} (${rounds} rounds) ==`); 41 const typed = runCase('typed-friendly', rounds, typedFn); 42 const unknown = runCase('type-unknown ', rounds, unknownFn); 43 44 if (typed.out !== unknown.out) { 45 throw new Error(`${title}: result mismatch (${typed.out} vs ${unknown.out})`); 46 } 47 48 const ratio = unknown.best / typed.best; 49 const delta = unknown.best - typed.best; 50 const winner = ratio >= 1 ? 'typed-friendly' : 'type-unknown'; 51 console.log(`speedup: ${ratio.toFixed(2)}x (winner: ${winner}, delta ${delta.toFixed(2)} ms)`); 52 return typed.out; 53} 54 55function forOfArrayTyped(rounds) { 56 const arr = [ 57 1, 3, 5, 7, 9, 11, 13, 15, 58 17, 19, 21, 23, 25, 27, 29, 31, 59 33, 35, 37, 39, 41, 43, 45, 47, 60 49, 51, 53, 55, 57, 59, 61, 63 61 ]; 62 let sum = 0; 63 for (let r = 0; r < rounds; r++) { 64 for (const v of arr) sum += v; 65 } 66 return sum; 67} 68 69function forOfArrayUnknown(rounds) { 70 const arr = [ 71 1, 3, 5, 7, 9, 11, 13, 15, 72 17, 19, 21, 23, 25, 27, 29, 31, 73 33, 35, 37, 39, 41, 43, 45, 47, 74 49, 51, 53, 55, 57, 59, 61, 63 75 ]; 76 const iterSrc = opaque(arr); 77 let sum = 0; 78 for (let r = 0; r < rounds; r++) { 79 for (const v of iterSrc) sum += v; 80 } 81 return sum; 82} 83 84function forOfStringTyped(rounds) { 85 const str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; 86 let sum = 0; 87 for (let r = 0; r < rounds; r++) { 88 for (const ch of str) sum += ch.length; 89 } 90 return sum; 91} 92 93function forOfStringUnknown(rounds) { 94 const str = opaque('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'); 95 let sum = 0; 96 for (let r = 0; r < rounds; r++) { 97 for (const ch of str) sum += ch.length; 98 } 99 return sum; 100} 101 102function arithmeticTyped(rounds) { 103 const a = 1.25; 104 const b = 3.75; 105 const c = 0.5; 106 const d = 9.125; 107 let acc = 0; 108 for (let i = 0; i < rounds; i++) { 109 acc = acc + (a * b) - (c / d) + (a + c) - (b - d); 110 } 111 return acc; 112} 113 114function arithmeticUnknown(rounds) { 115 const a = opaque(1.25); 116 const b = opaque(3.75); 117 const c = opaque(0.5); 118 const d = opaque(9.125); 119 let acc = 0; 120 for (let i = 0; i < rounds; i++) { 121 acc = acc + (a * b) - (c / d) + (a + c) - (b - d); 122 } 123 return acc; 124} 125 126function typeofGuardTyped(rounds) { 127 const x = 123; 128 let sum = 0; 129 for (let i = 0; i < rounds; i++) { 130 if (typeof x === 'number') sum += x; 131 else sum -= 1; 132 } 133 return sum; 134} 135 136function typeofGuardUnknown(rounds) { 137 const x = opaque(123); 138 let sum = 0; 139 for (let i = 0; i < rounds; i++) { 140 if (typeof x === 'number') sum += x; 141 else sum -= 1; 142 } 143 return sum; 144} 145 146const roundsForOfArray = Math.max(20000, Math.floor(70000 * SCALE)); 147const roundsForOfString = Math.max(15000, Math.floor(50000 * SCALE)); 148const roundsArithmetic = Math.max(500000, Math.floor(2500000 * SCALE)); 149const roundsTypeof = Math.max(500000, Math.floor(3000000 * SCALE)); 150 151console.log('compile-time type tracking benchmark'); 152console.log(`scale: ${SCALE}`); 153console.log(`repeats: ${REPEATS}`); 154console.log('usage: ./build/ant tests/bench_type_tracking.js [scale]'); 155 156let checksum = 0; 157checksum += reportPair('for..of array iterator hint', roundsForOfArray, forOfArrayTyped, forOfArrayUnknown); 158checksum += reportPair('for..of string iterator hint', roundsForOfString, forOfStringTyped, forOfStringUnknown); 159checksum += reportPair('numeric arithmetic specialization', roundsArithmetic, arithmeticTyped, arithmeticUnknown); 160checksum += reportPair('typeof guard folding', roundsTypeof, typeofGuardTyped, typeofGuardUnknown); 161 162console.log(`\nchecksum: ${checksum}`);