doc/help/Benchmark.md
The Benchmark dialog measures how fast the machine you're running on can extract, parse, and visualize frames through Serial Studio's data pipeline. It drives the real hot path, not a synthetic micro-benchmark, so the numbers it reports are the throughput your hardware would sustain on live data. Use it to verify a build, compare machines, or check that a parser or transform change hasn't regressed throughput.
This page describes the interactive, in-app dialog. For the headless form used in CI and
deployment gating, see Command-Line Interface;
both run the same HotpathBenchmark engine. For the architecture being measured, see
The Data Hotpath and Threading and Timing Guarantees.
Open the About window (the About toolbar button, authoring mode only), then click Benchmark. The dialog runs entirely on the local machine; nothing is uploaded.
The benchmark feeds newline-delimited synthetic frames (sine-wave numeric channels, plus
rotating non-numeric status words for the mixed phases) through the same chain that live data
takes: FrameReader extraction, the FrameBuilder decode/parse/transform stage, and the
downstream consumers. Each phase reports a sustained throughput in frames per second and
the wall-clock time it took to reach the target frame count.
Two workload selectors shape the run:
Two groups of checkboxes pick which phases run:
The Run button stays disabled until at least one stage and at least one data type are selected.
The data pipeline always runs first. Each selected stage then runs every parser engine
(Built-in, Lua, JavaScript) over each selected data type. The data-pipeline and parser phases
are gated (Pass/Fail); the data-export and dashboard phases are informational and
report n/a in the Result column.
| Phase | What it exercises | Gate (at default 256 K min-fps) |
|---|---|---|
| Data pipeline | Raw FrameReader extraction only: delimiter scan and dequeue, no parse. | 1024 K frames/s |
| Built-in parser (numeric) | Native C++ template over numeric channels. | 1024 K frames/s |
| Built-in parser (mixed) | Native template with trailing non-numeric string tokens. | 512 K frames/s |
| Lua parser (numeric) | parse() in Lua 5.4 over numeric channels. | 256 K frames/s |
| JavaScript parser (numeric) | parse() in QJSEngine over the same channels. | 128 K frames/s |
| Lua parser (mixed) | Lua parse() over the mixed workload. | 128 K frames/s |
| JavaScript parser (mixed) | JavaScript parse() over the mixed workload. | 64 K frames/s |
| Built-in / Lua / JavaScript + data export | Each engine, numeric and/or mixed, with every export/output consumer enabled (CSV, API, plus MDF4 / Sessions / gRPC where built). | informational |
| Built-in / Lua / JavaScript + dashboard | Each engine, numeric and/or mixed, feeding a full dashboard (multiplot, FFT, bar, LED, waterfall, GPS, 3D plot). | informational |
The gates are tiered off the minimum frame rate, so JavaScript is held to half its Lua
peer and the data pipeline to four times the parser baseline. This reflects the real cost
hierarchy: raw extraction is the cheapest stage, the Built-in template is faster than the
scripted engines, Lua's stack-based API is faster than QJSEngine's value boxing, and the
mixed workload (with toDouble failures on the string tokens) is heavier than the numeric one.
The same per-language ranking is described in
Frame Parser Scripting — Performance Tips.
The informational phases exist to show the cost of fanning out to consumers and to the dashboard, not to gate a build. Their throughput is expected to be lower than the gated phases.
A warning in the dialog states that the window stops responding while the benchmark runs. This is by design, and it's the same property that makes the hot path fast:
FrameReader and FrameBuilder run
on the main (GUI) thread; the benchmark drives them flat-out in a tight loop, so the event
loop can't repaint until the loop returns. See
Threading and Timing Guarantees
for why frame parsing lives on the main thread.The runner snapshots your session, runs the benchmark against a synthetic project, and restores everything when it finishes. Specifically, while the benchmark runs it:
When the run ends, the runner restores your operation mode, plot window, and consumer toggles to exactly what they were, and reloads your original project (or returns to the prior mode with a clean dashboard if no project was open). If you had a project open before benchmarking, it comes back automatically.
n/a for informational phases.n/a for the informational export and dashboard phases. A
gated phase fails if its throughput is below the tiered target shown above.A failing gated phase usually means the machine is too slow for the default 256 kHz target, the build is unoptimized (a debug build, or one without the shipped PGO profile), or a parser / transform change regressed throughput. The headless CLI form is what CI uses to enforce these gates per pull request and on the shipped binary; the dialog is the same measurement on demand.
Copy places the results table on the clipboard as a Markdown report; Clear empties the results table; Close dismisses the dialog (also clearing the table). None of these are available while a benchmark is running.
parse() API and the Lua-vs-JavaScript
performance characteristics the benchmark quantifies.