Skip to content

Instantly share code, notes, and snippets.

@jmcph4
Created August 22, 2026 01:08
Show Gist options
  • Select an option

  • Save jmcph4/0a0da6401ecf2a9a83a1c177e7cb6424 to your computer and use it in GitHub Desktop.

Select an option

Save jmcph4/0a0da6401ecf2a9a83a1c177e7cb6424 to your computer and use it in GitHub Desktop.

GC Benchmark Comparison: Copying vs. Mark-and-Sweep

Wall-clock timing of benchmarks/*.psh under --release, comparing the original Cheney-style copying collector (commit cc0c523) against the new in-place mark-and-sweep collector. Each benchmark was run once per build with a 240s timeout; both builds passed the full test suite.

Benchmark Original (copying GC) New (mark-and-sweep) Δ
alloc_objs.psh 42826ms 41224ms −3.7%
arr_get.psh 10018ms 10009ms ~0%
binary_tree.psh 15645ms 15838ms +1.2%
fft.psh 42ms 41ms ~0%
fib.psh 17353ms 16717ms −3.7%
for_loop.psh 14221ms 13523ms −4.9%
gc_alloc_speed.psh 22190ms 22321ms +0.6%
gc_many_objs.psh 47888ms 18459ms −61.5%
host_calls.psh 3929ms 3841ms −2.2%
linked_list.psh 9759ms 9893ms +1.4%
matrix_vec_mult.psh 278ms 274ms −1.4%
mlp.psh 23893ms 22985ms −3.8%
nbody.psh 25048ms 25259ms +0.8%
obj_get.psh 19546ms 19349ms −1.0%
ping_pong.psh 15564ms 15708ms +0.9%
quicksort.psh 10642ms 10284ms −3.4%
rasterize.psh 44983ms 43512ms −3.3%
sha256.psh 5700ms 5262ms −7.7%

Takeaway

The mark-and-sweep collector is essentially performance-neutral across the suite — every benchmark lands within ±5% of the original, well within normal run-to-run noise, except gc_many_objs.psh, which is 61% faster. That benchmark specifically stress-tests allocating and discarding many short-lived objects, which is where the copying collector's repeated semispace grow/shrink (and the mmap/mprotect calls that come with it) cost more than mark-sweep's in-place reclaim-and-reuse via the free list. No benchmark regressed meaningfully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment