janet-lang / janet

A dynamic language and bytecode vm
https://janet-lang.org
MIT License
3.43k stars 221 forks source link

Speed up `min`, `max` #1266

Closed primo-ppcg closed 1 year ago

primo-ppcg commented 1 year ago

Creates a helper macro so that the primitive comparators compile to vm ops directly. The boiler plating is approximately the same as would be generated by each, except that the key is advanced before the loop to avoid unnecessarily comparing the first value with itself. The result is approximately 4x faster for min and max, 5x faster for min-of and max-of, and roughly unchanged for extreme.

(use spork/test)
(use spork/misc)

(def rng (math/rng 12345))
(def a (randomize-array (range 100) rng))

(timeit-loop [:timeout 1] "min    " (min ;a))
(timeit-loop [:timeout 1] "max    " (max ;a))
(timeit-loop [:timeout 1] "min-of " (min-of a))
(timeit-loop [:timeout 1] "max-of " (max-of a))
(timeit-loop [:timeout 1] "extreme" (extreme < a))

master:

min     1.000s, 9.145µs/body
max     1.001s, 9.146µs/body
min-of  1.000s, 8.959µs/body
max-of  1.000s, 8.962µs/body
extreme 1.000s, 9.012µs/body

branch:

min     1.000s, 2.101µs/body
max     1.000s, 2.172µs/body
min-of  1.000s, 1.816µs/body
max-of  1.000s, 1.854µs/body
extreme 1.000s, 8.888µs/body

The stray comma before not= is necessary, oddly. With, it compiles to a single jmpni instruction. Without, it compiles to ldn, neq, jmpno.

sogaiu commented 1 year ago

Here are my numbers:

master (ee01045d):

$ JANET_PATH=~/src/spork/jpm_tree/lib ~/src/janet/build/janet ~/scratch/min-max.janet 
min     1.000s, 13.23µs/body
max     1.000s, 13.04µs/body
min-of  1.000s, 12.67µs/body
max-of  1.000s, 12.57µs/body
extreme 1.000s, 12.6µs/body

branch (6e897933):

$ JANET_PATH=~/src/spork/jpm_tree/lib ~/src/janet.primo-ppcg/build/janet ~/scratch/min-max.janet 
min     1.000s, 3.313µs/body
max     1.000s, 3.18µs/body
min-of  1.000s, 2.767µs/body
max-of  1.000s, 2.679µs/body
extreme 1.000s, 12.37µs/body

Test from various repositories were fine too :+1:

primo-ppcg commented 1 year ago

Here are my numbers:

Appreciated, as always 😄