I keep ignoring nim for some reason. How fast is it with all the checks on? The benchmarks for it julia, and swift typically turn off safety checks, which is not how I would run them.
That said, as a rough guideline, nim c -d=release can certainly be almost the same speed as -d=danger and is often within a few (single digits) percent. E.g.:
.../bu(main)$ nim c -d=useMalloc --panics=on --cc=clang -d=release -o=/t/rel unfold.nim
Hint: mm: orc; opt: speed; options: -d:release
61608 lines; 0.976s; 140.723MiB peakmem; proj: .../bu/unfold.nim; out: /t/rel [SuccessX]
.../bu(main)$ nim c -d=useMalloc --panics=on --cc=clang -d=danger -o=/t/dan unfold.nim
Hint: mm: orc; opt: speed; options: -d:danger
61608 lines; 2.705s; 141.629MiB peakmem; proj: .../bu/unfold.nim; out: /t/dan [SuccessX]
.../bu(main)$ seq 1 100000 > /t/dat
.../bu(main)$ /t
/t$ re=(chrt 99 taskset -c 2 env -i HOME=$HOME PATH=$PATH)
/t$ $re tim "./dan -n50 <dat>/n" "./rel -n50 <dat>/n"
225.5 +- 1.2 μs (AlreadySubtracted)Overhead
4177 +- 15 μs ./dan -n50 <dat>/n
4302 +- 17 μs ./rel -n50 <dat>/n
/t$ a (4302 +- 17)/(4177 +- 15)
1.0299 +- 0.0055
/t$ a 299./55
5.43636... # kurtosis=>5.4 sigmas is not so significant
Of course, as per my first sentence, the best benchmarks are your own applications run against your own data and its idiosyncratic distributions.EDIT: btw, /t -> /tmp which is a /dev/shm bind mount while /n -> /dev/null.