|
| 1 | +const { Parser: ParserV2New } = require('../dist/commonjs/aurelia-binding'); |
| 2 | +const { Parser: ParserV2 } = require('./v2/aurelia-binding'); |
| 3 | +const { Parser: ParserV1 } = require('./v1/aurelia-binding'); |
| 4 | + |
| 5 | +const v2new = new ParserV2New(); |
| 6 | +const v2 = new ParserV2(); |
| 7 | +const v1 = new ParserV1(); |
| 8 | + |
| 9 | +const colors = { |
| 10 | + Reset: '\x1b[0m', |
| 11 | + Bright: '\x1b[1m', |
| 12 | + Dim: '\x1b[2m', |
| 13 | + Underscore: '\x1b[4m', |
| 14 | + FgRed: '\x1b[31m', |
| 15 | + FgGreen: '\x1b[32m' |
| 16 | +}; |
| 17 | +const widths = { |
| 18 | + executionTime: 12, |
| 19 | + weight: 8, |
| 20 | + diffPercent: 9, |
| 21 | + expression: 35 |
| 22 | +}; |
| 23 | +const columns = { |
| 24 | + 0: { name: 'Weight', width: widths.weight }, |
| 25 | + 1: { name: 'Expression', width: widths.expression }, |
| 26 | + 2: { name: 'v1', width: widths.executionTime }, |
| 27 | + 3: { name: 'v2', width: widths.executionTime }, |
| 28 | + 4: { name: 'v1/v2', width: widths.diffPercent }, |
| 29 | + 5: { name: 'New', width: widths.executionTime }, |
| 30 | + 6: { name: 'v1/New', width: widths.diffPercent }, |
| 31 | + 7: { name: 'v2/New', width: widths.diffPercent } |
| 32 | +}; |
| 33 | +function diffText(elapsed, iA, iB) { |
| 34 | + const col = iB === 1 ? 4 : iB === 2 ? iA === 0 ? 6 : 7 : 0; // eslint-disable-line no-nested-ternary |
| 35 | + const a = elapsed[iA]; |
| 36 | + const b = elapsed[iB]; |
| 37 | + if (!(a && b)) return padLeft('', columns[col].width); |
| 38 | + const percent = Math.round((Math.max(a, b) / Math.min(a, b) - 1) * 100); |
| 39 | + const color = a < b ? colors.FgRed : colors.FgGreen; |
| 40 | + return color + padLeft(`${percent} %`, columns[col].width) + colors.Reset; |
| 41 | +} |
| 42 | +function elapsedText(elapsedArr, idx, iterations) { |
| 43 | + const col = idx === 0 ? 2 : idx === 1 ? 3 : 5; // eslint-disable-line no-nested-ternary |
| 44 | + let elapsed = Math.round(elapsedArr[idx] / iterations); |
| 45 | + let symbol = 'ns'; |
| 46 | + if (elapsed > 1000) { elapsed /= 1000; symbol = 'µs'; } |
| 47 | + if (elapsed > 1000) { elapsed /= 1000; symbol = 'ms'; } |
| 48 | + elapsed = (Math.round((elapsed + 0.00001) * 10) / 10).toString(); |
| 49 | + if (elapsed.indexOf('.') === -1) elapsed += '.0'; |
| 50 | + return padLeft(`${elapsed} ${symbol}`, columns[col].width); |
| 51 | +} |
| 52 | +function padLeft(str, desiredLength, ch) { |
| 53 | + while ((str = str.toString()).length < desiredLength) str = (ch ? ch : ' ') + str; |
| 54 | + return str; |
| 55 | +} |
| 56 | +function padRight(str, desiredLength, ch) { |
| 57 | + while ((str = str.toString()).length < desiredLength) str += ch ? ch : ' '; |
| 58 | + return str; |
| 59 | +} |
| 60 | +function log(str, colorBefore = colors.Reset, colorAfter = colors.Reset) { |
| 61 | + console.log(colorBefore, str, colorAfter); |
| 62 | +} |
| 63 | + |
| 64 | +const tests = [ |
| 65 | + { weight: 5, parsers: [v1, v2, v2new], expr: "'asdfasdfasdf'" }, |
| 66 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'true' }, |
| 67 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'false' }, |
| 68 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'null' }, |
| 69 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'undefined' }, |
| 70 | + { weight: 1, parsers: [v1, v2, v2new], expr: '1234' }, |
| 71 | + { weight: 1, parsers: [v1, v2, v2new], expr: '1234.5678' }, |
| 72 | + { weight: 1, parsers: [v1, v2, v2new], expr: '3.345e10' }, |
| 73 | + { weight: 10, parsers: [v1, v2, v2new], expr: 'foo' }, |
| 74 | + { weight: 10, parsers: [v1, v2, v2new], expr: 'foobar' }, |
| 75 | + { weight: 10, parsers: [v1, v2, v2new], expr: 'foo.bar' }, |
| 76 | + { weight: 10, parsers: [v1, v2, v2new], expr: 'foobar1234' }, |
| 77 | + { weight: 10, parsers: [v1, v2, v2new], expr: 'foobar.foobar' }, |
| 78 | + { weight: 5, parsers: [v1, v2, v2new], expr: 'foo.bar.baz' }, |
| 79 | + { weight: 5, parsers: [v1, v2, v2new], expr: 'fooBarBazQux' }, |
| 80 | + { weight: 5, parsers: [v1, v2, v2new], expr: 'fooBarBazQux.fooBarBazQux' }, |
| 81 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'fooBar.fooBar.fooBar3' }, |
| 82 | + { weight: 1, parsers: [v1, v2, v2new], expr: '!!foo && !!bar ? baz : qux' }, |
| 83 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'foo === null || foo === undefined' }, |
| 84 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'foo / 100 + (bar * -baz) % 2' }, |
| 85 | + { weight: 1, parsers: [v1, v2, v2new], expr: "foobar & someThing:'test'" }, |
| 86 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'foo.bar | baz & qux:42' }, |
| 87 | + { weight: 1, parsers: [v1, v2, v2new], expr: "foo | bar:a:'foo' & baz:a:b.c" }, |
| 88 | + { weight: 5, parsers: [v1, v2, v2new], expr: 'foo.bar' }, |
| 89 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'foo.bar.foo.bar' }, |
| 90 | + { weight: 5, parsers: [v1, v2, v2new], expr: 'handleEvent($event)' }, |
| 91 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'handleEvent({e: $event})' }, |
| 92 | + { weight: 1, parsers: [v1, v2, v2new], expr: '$this.foo($parent.bar[$index])' }, |
| 93 | + { weight: 1, parsers: [v1, v2, v2new], expr: '$parent.foo(bar[$index])' }, |
| 94 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'doStuff(foo, bar, baz)' }, |
| 95 | + { weight: 5, parsers: [v1, v2, v2new], expr: 'arr[i]' }, |
| 96 | + { weight: 1, parsers: [v1, v2, v2new], expr: '[[[]],[[]],[[]]]' }, |
| 97 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'x?x:x?x:x?x:x?x:x' }, |
| 98 | + { weight: 1, parsers: [v1, v2, v2new], expr: '{x:{x:{}},x:{x:{}}}' }, |
| 99 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'x||x&&x==x!=x<x>x<=x>=x+x-x*x%x/!x' }, |
| 100 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'x|x:x|x:x&x:x&x:x' }, |
| 101 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'x(x(x())(x(x())))(x(x()))' }, |
| 102 | + { weight: 1, parsers: [v1, v2, v2new], expr: 'a(b({a:b,c:d})[c({})[d({})]])' }, |
| 103 | + { weight: 1, parsers: [null, null, v2new], expr: 'ØÙçĊĎďĢģĤŌŸŹźLjljNJNjnjǍDZDzʃʄʅʆʇᵴᵷᵹᵺᵻᵼᶦᶧ' } |
| 104 | +]; |
| 105 | + |
| 106 | +const totalWidth = widths.weight + widths.expression + widths.executionTime * 3 + widths.diffPercent * 3; |
| 107 | +const hr = padRight('', totalWidth, '-'); |
| 108 | +const header = hr + '\n ' |
| 109 | + + padLeft('Execution time per parse', totalWidth) + '\n\n ' |
| 110 | + + padRight(columns[0].name, widths.weight) |
| 111 | + + padRight(columns[1].name, widths.expression) |
| 112 | + + padLeft(columns[2].name, columns[2].width) |
| 113 | + + padLeft(columns[3].name, columns[3].width) |
| 114 | + + padLeft(columns[4].name, columns[4].width) |
| 115 | + + padLeft(columns[5].name, columns[5].width) |
| 116 | + + padLeft(columns[6].name, columns[6].width) |
| 117 | + + padLeft(columns[7].name, columns[7].width) |
| 118 | + + '\n ' + hr; |
| 119 | + |
| 120 | +function run(iterations) { |
| 121 | + log(header); |
| 122 | + |
| 123 | + let parses = 0; |
| 124 | + const totalElapsed = new Uint32Array(3); |
| 125 | + for (let i = 0; i < tests.length; i++) { |
| 126 | + const { expr, parsers, weight } = tests[i]; |
| 127 | + msg = weight > 1 ? colors.Bright : ''; |
| 128 | + msg += padRight(weight, widths.weight); |
| 129 | + msg += padRight(expr, widths.expression) + colors.Reset; |
| 130 | + |
| 131 | + const elapsed = new Uint32Array(3); |
| 132 | + for (let j = 0; j < 3; j++) { |
| 133 | + const parser = parsers[j]; |
| 134 | + if (!parser) { |
| 135 | + msg += padLeft('-', widths.executionTime); |
| 136 | + if (j === 1) msg += padLeft('', widths.diffPercent); |
| 137 | + continue; |
| 138 | + } |
| 139 | + |
| 140 | + const count = iterations * weight; |
| 141 | + let k = count; |
| 142 | + const start = process.hrtime(); |
| 143 | + while (k--) { |
| 144 | + parser.parse(expr); |
| 145 | + parser.cache[expr] = null; |
| 146 | + } |
| 147 | + const end = process.hrtime(start); |
| 148 | + elapsed[j] = end[0] * 10e8 + end[1]; |
| 149 | + if (j === 2 && elapsed[0] && elapsed[1] && elapsed[2]) { |
| 150 | + parses += count; |
| 151 | + totalElapsed[0] += elapsed[0]; |
| 152 | + totalElapsed[1] += elapsed[1]; |
| 153 | + totalElapsed[2] += elapsed[2]; |
| 154 | + } |
| 155 | + msg += elapsedText(elapsed, j, count); |
| 156 | + |
| 157 | + if (j === 1) { |
| 158 | + msg += diffText(elapsed, 0, 1); |
| 159 | + } else if (j === 2) { |
| 160 | + msg += diffText(elapsed, 0, 2); |
| 161 | + msg += diffText(elapsed, 1, 2); |
| 162 | + } |
| 163 | + } |
| 164 | + |
| 165 | + log(msg); |
| 166 | + } |
| 167 | + log(hr); |
| 168 | + |
| 169 | + msg = colors.Bright + padRight(`Total execution time (${parses} parses)`, widths.weight + widths.expression); |
| 170 | + msg += elapsedText(totalElapsed, 0, 1); |
| 171 | + msg += elapsedText(totalElapsed, 1, 1); |
| 172 | + msg += diffText(totalElapsed, 0, 1); |
| 173 | + msg += colors.Bright + elapsedText(totalElapsed, 2, 1); |
| 174 | + msg += diffText(totalElapsed, 0, 2); |
| 175 | + msg += colors.Bright + diffText(totalElapsed, 1, 2); |
| 176 | + log(msg); |
| 177 | + log(hr); |
| 178 | +} |
| 179 | + |
| 180 | +run(10); |
0 commit comments