Skip to content

Commit 59a7d8d

Browse files
committed
feat: manually call v8 to optimize functions
1 parent 0477f5a commit 59a7d8d

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

packages/benchmark.js/src/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Benchmark from "benchmark";
2-
import measurement from "@codspeed/core";
2+
import { initCore, measurement, optimizeFunctionSync } from "@codspeed/core";
33
import { get as getStackTrace } from "stack-trace";
44
import path, { dirname } from "path";
55
import { findUpSync, Options } from "find-up";
@@ -18,12 +18,15 @@ function withCodSpeedBenchmark(bench: Benchmark): Benchmark {
1818
if (!measurement.isInstrumented()) {
1919
return bench;
2020
}
21+
initCore();
2122
const callingFile = getCallingFile();
2223
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2324
bench.run = function (options?: Benchmark.Options): Benchmark {
2425
const uri = callingFile + "::" + (bench.name ?? "unknown");
26+
const fn = bench.fn as CallableFunction;
27+
optimizeFunctionSync(fn);
2528
measurement.startInstrumentation();
26-
(bench.fn as CallableFunction)();
29+
fn();
2730
measurement.stopInstrumentation(uri);
2831
return bench;
2932
};

packages/core/src/index.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,25 @@ try {
2626
isBound: false,
2727
};
2828
}
29-
const measurement = m;
30-
export default measurement;
29+
export const measurement = m;
30+
31+
export const initCore = () => {
32+
// eslint-disable-next-line @typescript-eslint/no-var-requires
33+
require("v8").setFlagsFromString("--allow-natives-syntax");
34+
};
35+
36+
export const optimizeFunction = async (fn: CallableFunction) => {
37+
// Source: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#optimization-killers
38+
await fn(); //Fill type-info
39+
await fn(); // 2 calls are needed to go from uninitialized -> pre-monomorphic -> monomorphic
40+
eval("%OptimizeFunctionOnNextCall(fn)");
41+
await fn(); // optimize
42+
};
43+
44+
export const optimizeFunctionSync = (fn: CallableFunction) => {
45+
// Source: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#optimization-killers
46+
fn(); //Fill type-info
47+
fn(); // 2 calls are needed to go from uninitialized -> pre-monomorphic -> monomorphic
48+
eval("%OptimizeFunctionOnNextCall(fn)");
49+
fn(); // optimize
50+
};

packages/tinybench/src/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import measurement from "@codspeed/core";
1+
import { initCore, measurement, optimizeFunction } from "@codspeed/core";
22
import { get as getStackTrace } from "stack-trace";
33
import path, { dirname } from "path";
44
import { findUpSync, Options } from "find-up";
@@ -8,11 +8,12 @@ export function withCodSpeed(bench: Bench): Bench {
88
if (!measurement.isInstrumented()) {
99
return bench;
1010
}
11+
initCore();
1112
const callingFile = getCallingFile();
1213
bench.run = async () => {
1314
for (const task of bench.tasks) {
1415
const uri = callingFile + "::" + task.name;
15-
await task.warmup();
16+
await optimizeFunction(task.fn);
1617
measurement.startInstrumentation();
1718
await task.fn();
1819
measurement.stopInstrumentation(uri);

0 commit comments

Comments
 (0)