V
V
Vitaly Stolyarov2016-08-06 18:00:21
JavaScript
Vitaly Stolyarov, 2016-08-06 18:00:21

Emscripten - where is the performance?

Here for a simple program there are source codes in
C ++

#include <iostream>

using namespace std;

#include <sys/time.h>
#include <unistd.h>

static double GetMilliseconds(){
  struct timeval time;
  gettimeofday(&time, NULL);
  
  return (time.tv_sec*1000.0 + time.tv_usec/1000.0);
}


int i=0;
int fib(int x) {i++;
  if (x < 2) {
    return 1;
  } else {
    return fib(x - 1) + fib(x - 2);
  }
}


int main() {

double t0 = GetMilliseconds();


int result = fib(35);



double ms = GetMilliseconds()-t0;

cout << "time ms: "<< ms << "res: "<<i<<"-"<<result<<endl;


cin.get();

  return 0;
}

and js
var i=0;
    function fib(x) {i++;
      if (x < 2) {
      return 1;
      } else {
      return fib(x - 1) + fib(x - 2);
      }
    }
  
    window.onload = function(){


  
      var time = new Date().getTime();

    
    var result = fib(35);
    


      document.write(new Date().getTime()-time+"<br>res: "+i+"-"+result);


    }

In the main block, the number of operations is identical.
After [assembly and] launch, I get the following picture:
  1. pure JS 180-200ms
  2. em++ 500-600ms
  3. em++ -O3 180-200ms
  4. g++ 180-200ms
  5. g++ -O3 50-60ms

Why is that? Okay, there without -O3 gives out wild things. But the code compiled via em++ is far from the speed on g++ -O3 and is no faster than pure JS on the same V8. Moreover, the indicators are the same in FF, in Chrome.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Belyaev, 2016-08-06
@bingo347

I tried to write a recursive fibonacci in pure asm.js:

(function(std, env, heap) {
    'use asm';
    function fib(n) {
        n = n|0;
        if((n|0) < (2|0)) {
            return 1|0;
        }
        return (fib((n|0) - (1|0)) + fib((n|0) - (2|0)))|0;
    }
    return fib;
}(
    {},
    null,
    new ArrayBuffer(0)
));

Really slower than js
The reason is obvious: asm.js is not optimized in any way, these are ready-made instructions for a virtual machine (for example, v8)
Normal js is run through an optimizer before compilation, which successfully converts tail recursions into a loop
We conclude that emscripten is not yet able to optimize tail recursions
And by the way, what optimization option did you give in em++?
PS about performance, my hashing algorithm (crc64 with salt) after a complete rewrite from js to asm.js gave a performance increase of 21.7 times (node ​​6.3.1 v8 5.0.71.57)

A
Armenian Radio, 2016-08-06
@gbg

With such questions, you need to look at the assembler listing. I guess gcc threw out all the calculations and planted a constant.
He definitely had to unwind the recursion.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question