How we benchmark Dice Core
Scenarios, method, results and limitations of a reproducible comparison with other RPG dice libraries.
Ask the right question
A benchmark answers a narrow question: how many times can an implementation perform this operation in this environment? It does not by itself measure API quality, rules coverage, random-source security or visual experience. That is why we publish the Dice Core comparison with three JavaScript libraries together with its conditions.
The result is straightforward: Dice Core did not lead throughput in the five simple scenarios measured. It still completed tens of thousands of full rolls per second on the test machine. A claim such as “the fastest dice library in the world” would not follow from this evidence.
Packages and operations
The suite pins versions in a separate scripts/benchmarks/package-lock.json:
| Library | Version | Timed operation |
|---|---|---|
| @erpg/dicecore | 3.7.1 | rollRpgDice(expression).total |
| @dice-roller/rpg-dice-roller | 5.5.1 | new DiceRoll(expression).total |
| @randsum/roller | 4.0.0 | roll(expression).total |
| dice-roller-parser | 0.1.8 | roller.roll(expression).value |
Each operation calls the default public API with the same expression and reads the numeric total. Dice Core caches the compiled expression after warmup; this suite leaves every package’s default cache behavior in place. A checksum consumes the values so results are not ignored. Initial import, networking, UI, GPU work and Dice View animation are outside the test.
Equivalent scenarios
We use five common rules:
| Expression | Rule |
|---|---|
1d20 |
One twenty-sided die |
2d6+3 |
Two d6 plus a modifier |
4d6kh3 |
Four d6, keep the highest three |
10d6 |
Ten d6 |
3d8+2d6 |
Different die sizes |
For keep-highest, RANDSUM uses its equivalent 4d6L notation (drop lowest). The expression is identical in the other scenarios. Before timing, the script validates one hundred results per library and scenario against the allowed range.
Repetitions and environment
The script warms each implementation, calibrates each library separately to roughly 250 ms per sample and records seven timed samples. We publish the median operations per second. Library order rotates between samples; garbage collection runs before each sample, outside the timed region.
The current results were collected with Node.js 24.18.0 on Windows using an AMD Ryzen 5 5500. Run the suite on your machine for another reading:
cd scripts/benchmarks
npm ci
npm run bench
The command rewrites results.json. The results page shows measured rates and the date. The implementation lives in scripts/benchmarks/benchmark.mjs.
Limitations
Dice Core returns structured dice, groups, events and replay metadata. The comparison packages return different amounts and shapes of data. This test reads their totals and does not normalize output depth.
We also use each library’s default random source. Dice Core uses crypto.getRandomValues without a seed. Different RNG costs and cache strategies affect throughput. Do not extrapolate these values to browsers, explosive expressions, system-specific mechanics, memory usage or 3D rendering.
For practical integration choices, continue with the performance guide.