Grimoire-
Command
.es

GNU+Linux command memo

Nim js fib benchmark

Mesure de performance du code JavaScript compilé par Nim.

Here is the code of a Nim version of the drujensen's Recursive Fibonacci Benchmark.

proc fib(n: int): int =
  if n <= 1:
    return n
  return fib(n - 1) + fib(n - 2)

echo fib(47)

The expected result is 2 971 215 073.

1. Nim interpretation

$ time nim e fib.nim
2971215073
nim e fib.nim  6288,83s user 1,40s system 99% cpu 1:45:08,73 total (1)
1 Interpreted Nim is not meant for high speed, but it allows to replace Makefiles and adminsys scripting without developper mind-context change. A memoized version is interpreted in 0,40s.

2. Native Nim compilation

$ time nim c -d:release -r fib.nim (1)
2971215073
nim c -d:release -r fib.nim  7,95s user 0,07s system 100% cpu 7,973 total (2)
$ time ./fib
2971215073
./fib  4,63s user 0,00s system 99% cpu 4,635 total
1 Nim Compiler Version 1.6.6
2 Every measures have been made 5x, where consistant and are faithfully represented by the shown outputs.

3. JavaScript Nim compilation

$ time nim js -d:release -o:fib.nim.release.js fib.nim (1)
nim js -d:release -o:fib.nim.release.js fib.nim  0,29s user 0,03s system 99% cpu 0,322 total
$ time node fib.nim.release.js (2)
node fib.nim.release.js  71,53s user 0,03s system 99% cpu 1:11,71 total
$ time js78 fib.nim.release.js (3)
js78 fib.nim.release.js  34,48s user 0,01s system 99% cpu 34,510 total
1 Produces a fib.nim.release.js of 15ko. Would be 4,8ko with -d:danger with no difference in performances.
2 Well, to be true I had to use uint64 instead of simple int to avoid an OverflowDefect exception
3 Surprisingly Mozilla Firefox’s js78 JavaScript engine is twice as fast as Google Chrome’s nodejs v19.0.0 engine.

4. Native JavaScript solution

function fib(n) {
  if (n <= 1)
		return n
  return fib(n - 1) + fib(n - 2)
}

console.log(fib(47))

Size of the file is 100 octets.

$ time node fib.node.js
2971215073
node fib.node.js  65,16s user 0,01s system 99% cpu 1:05,21 total
$ time js78 fib.node.js
2971215073
js78 fib.node.js  33,77s user 0,01s system 99% cpu 33,808 total

Again, js78 uses 50% of the time needed by node.

What’s interesting here is that Nim generated JavaScript is not loosing in performance compared to native JavaScrip code, despite the expension rate of the code itself (mostly runtime checks added by Nim compilator I assume).

To be honest, if I use uint64 everywhere for the Nim version I achieve comparable results with drujensen's benchmark with my Intel® Core™ m7-6Y75 compared to its Intel Xeon 3.1Ghz (AWS EC2 - m5.large 2 vCPU, 2022-01-18) (both running at the same peak performance max speed), and he measures ±30s for node v17.3.0. So I can’t explain the horrible performance I get here with node.

5. Benchmark hardware

The computer used for this tests is an Asus UX305CA, Intel Core i7 M (6Y75 / 600MHz - 3,1GHz), 8Go DDR3 1866MHz.

A lot more hardware info is available here : Memo_10.