Skip to content

Commit c47e237

Browse files
authored
Merge pull request #25 from nberlette/perf/add-benchmarks
perf: add performance benchmarks
2 parents 16c7991 + 8ebcde3 commit c47e237

1 file changed

Lines changed: 179 additions & 0 deletions

File tree

bench/math.bench.ts

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
// deno-lint-ignore-file ban-types
2+
import { abs } from "../src/abs.ts";
3+
import { acos } from "../src/acos.ts";
4+
import { acosh } from "../src/acosh.ts";
5+
import { asin } from "../src/asin.ts";
6+
import { asinh } from "../src/asinh.ts";
7+
import { atan } from "../src/atan.ts";
8+
import { atan2 } from "../src/atan2.ts";
9+
import { atanh } from "../src/atanh.ts";
10+
import { cbrt } from "../src/cbrt.ts";
11+
import { ceil } from "../src/ceil.ts";
12+
import { clz32 } from "../src/clz32.ts";
13+
import { cos } from "../src/cos.ts";
14+
import { cosh } from "../src/cosh.ts";
15+
import { exp } from "../src/exp.ts";
16+
import { expm1 } from "../src/expm1.ts";
17+
import { floor } from "../src/floor.ts";
18+
import { fround } from "../src/fround.ts";
19+
import { hypot } from "../src/hypot.ts";
20+
import { imul } from "../src/imul.ts";
21+
import { log } from "../src/log.ts";
22+
import { log1p } from "../src/log1p.ts";
23+
import { log2 } from "../src/log2.ts";
24+
import { log10 } from "../src/log10.ts";
25+
import { max } from "../src/max.ts";
26+
import { min } from "../src/min.ts";
27+
import { pow } from "../src/pow.ts";
28+
import { random } from "../src/random.ts";
29+
import { round } from "../src/round.ts";
30+
import { sign } from "../src/sign.ts";
31+
import { sin } from "../src/sin.ts";
32+
import { sinh } from "../src/sinh.ts";
33+
import { sqrt } from "../src/sqrt.ts";
34+
import { tan } from "../src/tan.ts";
35+
import { tanh } from "../src/tanh.ts";
36+
import { trunc } from "../src/trunc.ts";
37+
38+
const absInputs = [-1000, -10.5, -1, -0, 0, 1, 10.5, 1000];
39+
const acosInputs = [-1, -0.75, -0.5, 0, 0.5, 0.75, 1];
40+
const acoshInputs = [1, 1.001, 1.5, 2, 10, 100];
41+
const asinInputs = [-1, -0.75, -0.5, 0, 0.5, 0.75, 1];
42+
const asinhInputs = [-10, -1, -0.5, 0, 0.5, 1, 10];
43+
const atanInputs = [-10, -1, -0.5, 0, 0.5, 1, 10];
44+
const atanhInputs = [-0.99, -0.5, -0.1, 0, 0.1, 0.5, 0.99];
45+
const atan2Pairs: Array<[number, number]> = [
46+
[-1, -1],
47+
[-1, 1],
48+
[1, -1],
49+
[1, 1],
50+
[0.5, 2],
51+
[2, 0.5],
52+
];
53+
const cbrtInputs = [-1000, -27, -8, -1, 0, 1, 8, 27, 1000];
54+
const ceilInputs = [-10.9, -1.1, -0.5, 0, 0.5, 1.1, 10.9];
55+
const floorInputs = [-10.9, -1.1, -0.5, 0, 0.5, 1.1, 10.9];
56+
const roundInputs = [-10.9, -1.5, -1.1, -0.5, 0, 0.5, 1.1, 1.5, 10.9];
57+
const truncInputs = [-10.9, -1.5, -1.1, -0.5, 0, 0.5, 1.1, 1.5, 10.9];
58+
const clz32Inputs = [0, 1, 2, 3, 4, 8, 16, 1024, 0x7fffffff, 0xffffffff];
59+
const cosInputs = [
60+
-Math.PI,
61+
-Math.PI / 2,
62+
-1,
63+
-0.5,
64+
0,
65+
0.5,
66+
1,
67+
Math.PI / 2,
68+
Math.PI,
69+
];
70+
const coshInputs = [0, 0.5, 1, 2, 3, 4];
71+
const expInputs = [-5, -1, -0.5, 0, 0.5, 1, 2, 5];
72+
const expm1Inputs = [-1, -0.5, -0.1, 0, 0.1, 0.5, 1];
73+
const froundInputs = [0, 0.1, -0.1, 1 / 3, Math.PI, -Math.E, 1e10, -1e-10];
74+
const hypotSets: number[][] = [
75+
[3, 4],
76+
[5, 12],
77+
[1, 2, 3],
78+
[0.5, 2.5, 7.75],
79+
[-3, -4],
80+
[1, 1, 1, 1, 1],
81+
];
82+
const imulPairs: Array<[number, number]> = [
83+
[0, 0],
84+
[1, 2],
85+
[-1, 2],
86+
[12345, 6789],
87+
[-12345, 6789],
88+
[0x7fffffff, 0xffff],
89+
];
90+
const logInputs = [0.1, 0.5, 1, 2, 10, 100, Math.E, Math.PI];
91+
const log1pInputs = [-0.9, -0.5, -0.1, 0, 0.1, 0.5, 1, 10];
92+
const log2Inputs = [0.125, 0.5, 1, 2, 4, 8, 16, 128, 1024];
93+
const log10Inputs = [0.1, 0.5, 1, 2, 10, 100, 1000, 1e6];
94+
const maxMinSets: number[][] = [
95+
[-1, 0, 1],
96+
[3, 5, 2, 9],
97+
[-10, -5, -1],
98+
[1.5, 2.5, 3.5, 4.5],
99+
[Number.MIN_SAFE_INTEGER, 0, Number.MAX_SAFE_INTEGER],
100+
];
101+
const powPairs: Array<[number, number]> = [
102+
[2, 3],
103+
[10, 2],
104+
[2, -2],
105+
[Math.E, Math.PI],
106+
[0.5, 3],
107+
[9, 0.5],
108+
];
109+
const signInputs = [-10, -1, -0, 0, 0.1, 1, 10];
110+
const sinInputs = cosInputs;
111+
const sinhInputs = [-3, -1, -0.5, 0, 0.5, 1, 3];
112+
const sqrtInputs = [0, 0.25, 0.5, 1, 2, 10, 100, 1000];
113+
const tanInputs = [-1, -0.5, -0.25, 0, 0.25, 0.5, 1];
114+
const tanhInputs = [-3, -1, -0.5, 0, 0.5, 1, 3];
115+
116+
type FunctionKeys<T> = keyof {
117+
[K in keyof T as T[K] extends Function ? K : never]: 0;
118+
};
119+
120+
function bench<
121+
K extends FunctionKeys<Math>,
122+
F extends Math[K],
123+
P extends Parameters<F>,
124+
>(name: K, nativeFn: F, libFn: F, sets: (P extends [number] ? number : P)[]) {
125+
Deno.bench({ name: `Math.${name}`, group: name }, () => {
126+
let sum = 0;
127+
for (let i = 0; i < sets.length; i++) {
128+
sum += Reflect.apply(nativeFn, null!, ([] as any[]).concat(sets[i]));
129+
}
130+
if (Number.isNaN(sum)) throw new Error("sum is NaN");
131+
});
132+
133+
Deno.bench(
134+
{ name: `@nick/math.${name}`, group: name, baseline: true },
135+
() => {
136+
let sum = 0;
137+
for (let i = 0; i < sets.length; i++) {
138+
sum += Reflect.apply(libFn, null!, ([] as any[]).concat(sets[i]));
139+
}
140+
if (Number.isNaN(sum)) throw new Error("sum is NaN");
141+
},
142+
);
143+
}
144+
145+
bench("abs", Math.abs, abs, absInputs);
146+
bench("acos", Math.acos, acos, acosInputs);
147+
bench("acosh", Math.acosh, acosh, acoshInputs);
148+
bench("asin", Math.asin, asin, asinInputs);
149+
bench("asinh", Math.asinh, asinh, asinhInputs);
150+
bench("atan", Math.atan, atan, atanInputs);
151+
bench("atanh", Math.atanh, atanh, atanhInputs);
152+
bench("atan2", Math.atan2, atan2, atan2Pairs);
153+
bench("cbrt", Math.cbrt, cbrt, cbrtInputs);
154+
bench("ceil", Math.ceil, ceil, ceilInputs);
155+
bench("clz32", Math.clz32, clz32, clz32Inputs);
156+
bench("cos", Math.cos, cos, cosInputs);
157+
bench("cosh", Math.cosh, cosh, coshInputs);
158+
bench("exp", Math.exp, exp, expInputs);
159+
bench("expm1", Math.expm1, expm1, expm1Inputs);
160+
bench("floor", Math.floor, floor, floorInputs);
161+
bench("fround", Math.fround, fround, froundInputs);
162+
bench("hypot", Math.hypot, hypot, hypotSets);
163+
bench("imul", Math.imul, imul, imulPairs);
164+
bench("log", Math.log, log, logInputs);
165+
bench("log1p", Math.log1p, log1p, log1pInputs);
166+
bench("log2", Math.log2, log2, log2Inputs);
167+
bench("log10", Math.log10, log10, log10Inputs);
168+
bench("max", Math.max, max, maxMinSets);
169+
bench("min", Math.min, min, maxMinSets);
170+
bench("pow", Math.pow, pow, powPairs);
171+
bench("random", Math.random, random, Array.from({ length: 1024 }, () => []));
172+
bench("round", Math.round, round, roundInputs);
173+
bench("sign", Math.sign, sign, signInputs);
174+
bench("sin", Math.sin, sin, sinInputs);
175+
bench("sinh", Math.sinh, sinh, sinhInputs);
176+
bench("sqrt", Math.sqrt, sqrt, sqrtInputs);
177+
bench("tan", Math.tan, tan, tanInputs);
178+
bench("tanh", Math.tanh, tanh, tanhInputs);
179+
bench("trunc", Math.trunc, trunc, truncInputs);

0 commit comments

Comments
 (0)