1const REPORT_URL = 'http://localhost:8081/report_perf_data' 2// Set this to enforce that the perf server must be up. 3// Typically used for debugging. 4const fail_on_no_perf = false; 5 6function benchmarkAndReport(benchName, setupFn, testFn, teardownFn) { 7 try { 8 let ctx = {}; 9 // warmup 3 times (arbitrary choice) 10 setupFn(ctx); 11 testFn(ctx); 12 testFn(ctx); 13 testFn(ctx); 14 teardownFn(ctx); 15 16 ctx = {}; 17 setupFn(ctx); 18 let start = Date.now(); 19 let now = start; 20 times = 0; 21 // See how many times we can do it in 100ms (arbitrary choice) 22 while (now - start < 100) { 23 testFn(ctx); 24 now = Date.now(); 25 times++; 26 } 27 28 teardownFn(ctx); 29 30 // Try to make it go for 2 seconds (arbitrarily chosen) 31 // Since the pre-try took 100ms, multiply by 20 to get 32 // approximate tries in 2s (unless now - start >> 100 ms) 33 let goalTimes = times * 20; 34 ctx = {}; 35 setupFn(ctx); 36 times = 0; 37 start = Date.now(); 38 while (times < goalTimes) { 39 testFn(ctx); 40 times++; 41 } 42 const end = Date.now(); 43 teardownFn(ctx); 44 45 const us = (end - start) * 1000 / times; 46 console.log(benchName, `${us} microseconds`) 47 return _report(us, benchName); 48 } catch(e) { 49 console.error('caught error', e); 50 return Promise.reject(e); 51 } 52} 53 54// The same as benchmarkAndReport, except expects the third parameter, testFn, to return a promise 55async function asyncBenchmarkAndReport(benchName, setupFn, testFn, teardownFn) { 56 try { 57 let ctx = {}; 58 // warmup 3 times (arbitrary choice) 59 setupFn(ctx); 60 await testFn(ctx); 61 await testFn(ctx); 62 await testFn(ctx); 63 teardownFn(ctx); 64 65 ctx = {}; 66 setupFn(ctx); 67 let start = Date.now(); 68 let now = start; 69 times = 0; 70 // See how many times we can do it in 100ms (arbitrary choice) 71 while (now - start < 100) { 72 await testFn(ctx); 73 now = Date.now(); 74 times++; 75 } 76 77 teardownFn(ctx); 78 79 // Try to make it go for 2 seconds (arbitrarily chosen) 80 // Since the pre-try took 100ms, multiply by 20 to get 81 // approximate tries in 2s (unless now - start >> 100 ms) 82 let goalTimes = times * 20; 83 ctx = {}; 84 setupFn(ctx); 85 times = 0; 86 start = Date.now(); 87 while (times < goalTimes) { 88 await testFn(ctx); 89 times++; 90 } 91 const end = Date.now(); 92 teardownFn(ctx); 93 94 const us = (end - start) * 1000 / times; 95 console.log(benchName, `${us} microseconds`) 96 return _report(us, benchName); 97 } catch(e) { 98 console.error('caught error', e); 99 return Promise.reject(e); 100 } 101} 102 103 104function _report(microseconds, benchName) { 105 return fetch(REPORT_URL, { 106 method: 'POST', 107 mode: 'no-cors', 108 headers: { 109 'Content-Type': 'application/json', 110 }, 111 body: JSON.stringify({ 112 'bench_name': benchName, 113 'time_us': microseconds, 114 }) 115 }).then(() => console.log(`Successfully reported ${benchName} to perf aggregator`)); 116} 117 118function reportError(done) { 119 return (e) => { 120 console.log("Error with fetching. Likely could not connect to aggegator server", e.message); 121 if (fail_on_no_perf) { 122 expect(e).toBeUndefined(); 123 } 124 done(); 125 }; 126} 127