Skip to content

Profiling ​

Profiling is disabled by default. Enable it when constructing the engine, then bracket only the work you want to measure.

Sampling profiler ​

Sampling answers where script time went with low overhead:

csharp
var engine = new Engine(options => options.Profiling.Enabled = true);

engine.Diagnostics.StartSampling();
engine.Execute(script, "workload.js");
var profile = engine.Diagnostics.StopSampling();

using var output = File.Create("profile.json");
profile.WriteTo(output);

Open the result in Firefox Profiler. Frames are categorized as script, Jint built-in, or host interop. Samples are taken at interpreter check points, not by another thread, so a long host callback or indivisible built-in appears as time at its calling frame. The default one-millisecond interval is a floor, not a scheduling guarantee.

SamplingOptions.MaxSamples bounds storage; dropped samples are reported by SampledProfile.DroppedSampleCount. Sampling APIs are preview and produce the JINT0002 diagnostic unless acknowledged.

Evented profiler ​

Evented profiling records call boundaries exactly and has a cost per call:

csharp
var engine = new Engine(options => options.Profiling.Enabled = true);

engine.Diagnostics.StartProfiling();
engine.Execute(script, "workload.js");
var profile = engine.Diagnostics.StopProfiling();

using var output = File.Create("profile.speedscope.json");
profile.WriteSpeedscopeJson(output);

Open the result in speedscope. Options.Profiling.MaxEvents caps the session; when reached, ScriptProfile.Truncated is set and the recorded event stream remains balanced.

Sampling and evented sessions are independent and may run together. Both record on the engine-owning thread; do not inspect a running engine from another thread. Use a CLR profiler to investigate time spent entirely inside host callbacks.