unisonweb / unison

A friendly programming language from the future
https://unison-lang.org
Other
5.81k stars 271 forks source link

Statically resolve literal types at code-gen #5373

Closed ChrisPenner closed 1 month ago

ChrisPenner commented 1 month ago

Overview

Found a Map Lookup on a Reference for every numerical BLit instruction we process 😬; Instead, do the lookup statically ahead of time when generating the code.

Unsurprisingly this helps the most with the micro benchmarks which do arithmetic on literals, we see a 1.2X improvement on the counting benchmarks, but it should help a little with any number-literal heavy loops and such.

Benchmarks

Trunk -> This branch

Decode Nat
740ns -> 653ns

Generate 100 random numbers 
464.203µs -> 411.53µs

Count to 1 million
440.3634ms ->  364.804ms

Json parsing (per document)
376.44µs -> 360.04µs

Count to N (per element)
521ns -> 440ns

Count to 1000
527.065µs -> 440.988µs

Mutate a Ref 1000 times 
980.655µs -> 842.221µs

CAS an IO.ref 1000 times 
1.260218ms -> 1.141522ms

List.range (per element)
644ns -> 599ns

List.range 0 1000 
660.021µs -> 604.377µs

Set.fromList (range 0 1000)
3.024044ms -> 2.824032ms

Map.fromList (range 0 1000)
2.279482ms -> 2.113257ms

Map.lookup (1k element map)
5.775µs -> 5.239µs

Map.insert (1k element map)
14.5µs -> 13.019µs

List.at (1k element list)
584ns -> 481ns

Text.split /
40.354µs -> 40.099µs

Implementation notes

Interesting/controversial decisions

Pretty uncontroversial changes with a strictly positive benefit.