Skip to main content

InfArray Benchmarks

Benchmarks comparing InfArray against a Luau table on the same workloads. Every workload stays under Luau's 2^26 per-table limit so the regular table is a fair baseline. These measure the overhead InfArray's chunking adds, not the cases where a table simply can't compete (i.e. once you cross 2^26 elements, the table stops being an option at all).

This page mirrors benchmark/README.md. The results table is regenerated by lute run benchmark/run.luau --md.

Running

From the repo root, with Lute on your PATH:

# Print results to the console
lute run benchmark/run.luau

# Re-run and rewrite the results table in this file
lute run benchmark/run.luau --md

# Only the benchmarks whose title matches a substring
lute run benchmark/run.luau --filter get

# Trade speed for accuracy (more timed samples)
lute run benchmark/run.luau --samples 10

# Quick pass at 10% of each workload size
lute run benchmark/run.luau --scale 0.1

Adding a benchmark

  1. Copy an existing file in cases/ to cases/yourcase.bench.luau.
  2. Fill in title, n, and the variants.
  3. Add a require("./cases/yourcase.bench") line to the SPECS list in run.luau.

Interpreting the numbers

InfArray will always be slower per element than a native table. It does index math and an extra chunk lookup on every access. The point of the library is capacity, not speed. It holds more than 2^26 elements, which a single Luau table cannot. Use these benchmarks to keep that per-element overhead in check as the implementation changes, not to "beat" the table.


Results

CPU: AMD Ryzen 9 9950X 16-Core Processor
OS: Windows_NT (x86_64)
Date: 2026-06-23 11:49

PushBack - append N elements

Workload size: n = 4_194_304

ImplementationTime/opTotalThroughputvs baseline
InfArray48.6 ns203.96 ms20.56 M/s6.05× slower
Luau table8.0 ns33.71 ms124.44 M/s1.00× (baseline)

Set - overwrite N in-range elements

Workload size: n = 4_194_304

ImplementationTime/opTotalThroughputvs baseline
InfArray31.4 ns131.65 ms31.86 M/s9.72× slower
Luau table3.2 ns13.54 ms309.67 M/s1.00× (baseline)

Get - sequential read of N elements

Workload size: n = 4_194_304

InfArray uses the hoisted free function local Get = InfArray.Get.

ImplementationTime/opTotalThroughputvs baseline
InfArray26.7 ns111.92 ms37.48 M/s8.33× slower
Luau table3.2 ns13.44 ms312.15 M/s1.00× (baseline)

Get - random-access read of N elements

Workload size: n = 4_194_304

ImplementationTime/opTotalThroughputvs baseline
InfArray104.4 ns437.80 ms9.58 M/s2.85× slower
Luau table36.7 ns153.76 ms27.28 M/s1.00× (baseline)

Iterate - visit every present element

Workload size: n = 4_194_304

Iterate pays a callback per element

ImplementationTime/opTotalThroughputvs baseline
InfArray13.7 ns57.65 ms72.75 M/s5.23× slower
Luau table2.6 ns11.02 ms380.59 M/s1.00× (baseline)

for index, value in arr via __iter

Workload size: n = 4_194_304

__iter pays a closure call per element

ImplementationTime/opTotalThroughputvs baseline
InfArray28.7 ns120.31 ms34.86 M/s11.29× slower
Luau table2.5 ns10.66 ms393.51 M/s1.00× (baseline)

Find - linear search with needle at the end

Workload size: n = 4_194_304

ImplementationTime/opTotalThroughputvs baseline
InfArray3.9 ns16.17 ms259.44 M/s2.07× slower
Luau table1.9 ns7.83 ms535.97 M/s1.00× (baseline)

Results above are regenerated by lute run benchmark/run.luau --md. They are machine-specific. Treat them as relative ratios.