# System setup

System: Linux (4.11.3-1-ARCH) 64bit on i5-3475S CPU @ 2.90GHz, 8205MB RAM

Software versions:

  * Nim 0.17.0
  * emscripten 1.37.12
  * clang 4.0.0
  * Firefox 53.0.3 (64-bit)
  * Chromium 59.0.3071.86 (64-Bit)



# Benchmark results

Benchmarks were cloned from 
[https://github.com/def-/nim-benchmarksgame](https://github.com/def-/nim-benchmarksgame)
 and modified to run and give useable time measurements in the browser (source 
not yet on GitHub, will follow). Nim used clang for the native target and emcc 
(the emscripten compiler) for the Webassembly (wasm) and Asm.js targets. 
Results are given in seconds with 30000000 cycles for each benchmark:

|  | Ffox | Ffox | Ffox | Chrom | Chrom | Chrom  
---|---|---|---|---|---|---|---  
benchmark | native | wasm | asmjs | nim js | wasm | asmjs | nim js  
n-body problem (float64) | 3.43 | 4.06 | 3.94 | 13.10 | 5.56 | 4.87 | 5.46  
fibonacci (iterative, int64) | 0.69 | 1.26 | 5.38 | 1.29 | 1.52 | 11.27 | 1.93  
fibonacci (iterative, int32) | 0.90 | 0.99 | 1.07 | 1.35 | 1.06 | 1.04 | 1.94  
fibonacci (tail recursive, int64) | 0.91 | 1.28 | 7.76 | 4.00 | 1.31 | 10.33 | 
6.34  
fibonacci (tail recursive, int32) | 0.65 | 0.98 | 0.99 | 4.05 | 1.02 | 1.12 | 
6.35  
  
WebAssembly is the winner for me, it shows solid and consistent performance 
pretty close to native code. Since wasm is a 32-bit compilation target for now, 
the performance drop with 64-bit calculations was to be expected. In the 
JavaScript realm, i.e. for the asmjs and nim js targets, things get more 
volatile. The Asm.js code has a massive problem with 64-bit integers. 
JavaScript code generated by Nim holds up remarkably well, probably because it 
looks a lot like Asm.js already and is probably treated as such where possible 
by browsers. I didn't expect tail recursion to help performance in Javascript 
code, but that it is such a problem baffles me.

# Compilation details

The local NIM config file (nim.cfg) used was: 
    
    
    cc = clang
    @if emscripten:
       clang.exe = "emcc"
       clang.linkerexe = "emcc"
       clang.options.linker = ""
       cpu = "i386"
       @if wasm:
          passC = "-s WASM=1 -s 'BINARYEN_METHOD=\"native-wasm\"' -Iemscripten"
          passL = "-O3 -s WASM=1 -s 'BINARYEN_METHOD=\"native-wasm\"' 
-Lemscripten"
       @elif asmjs:
          passC = "-s ASM_JS=1 --separate-asm -Iemscripten"
          passL = "-O3 -s ASM_JS=1 --separate-asm -Lemscripten"
       @else:
          # this should produce JavaScript, but actually compiles to asm.js 
with -O1 or higher
          passC = "-Iemscripten"
          passL = "-Lemscripten"
       @end
    @end
    

Compiler commands:

  * Native target:
    nim c -d:release bench.nim
  * WebAssembly target
    nim c -d:emscripten -d:wasm -d:release -o:bench-wasm.html bench.nim
  * asm.js target (note passC and passL in nim.cfg):
    nim c -d:emscripten -d:asmjs -d:release -o:bench-asmjs.html bench.nim
  * Experimental Nim JS target:
    nim js -d:release -o:bench.js bench.nim


Reply via email to