Why is WebAssembly this slow as compared to JavaScript?
up vote
3
down vote
favorite
Today I decided to play around with WebAssembly for the very first time. So, I wrote this little Fibonacci program in C++:
#include <iostream>
#include <chrono>
int fib(int n) {
if(n==0) {
return 0;
} else if(n==1) {
return 1;
} else {
return fib(n-1) + fib(n-2);
}
}
int main() {
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
int sum = 0;
for (int i = 0; i < 35; ++i) {
sum += fib(i);
}
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> dur = t2 - t1;
std::cout << sum << std::endl;
std::cout << dur.count() << std::endl;
}
And compiled it into Web Assembly
(WA from now onwards) using the following command:
emcc fib.cpp -s WASM=1 -o fib.html
Then, after loading the resulting .html
file into the browser, the output I got was 14930351 592.8
, which means that WA took almost 600 milliseconds
.
Then, I wrote a JS equivalent of the same program, as follows:
export function fib(n) {
return n === 0 ? 0 : (n === 1 ? 1 : fib(n-1) + fib(n-2));
}
export function fibSum(n) {
let sum = 0;
for (let i = 0; i < n; i++) {
sum += fib(i)
}
return sum;
}
I used performance.now()
to measure the elapsed time in milliseconds to calculate fibSum(35)
, which gave an output of 347.200 milliseconds
on Chrome.
I get it that WA is very new hence the compiler must be missing some optimisations as compared to the V8 engine and it takes time to call WA code from the browser and everything but I was not expecting it to be this slow.
Thoughts? Have I not created a proper test case to compare the two?
javascript performance web webassembly
|
show 2 more comments
up vote
3
down vote
favorite
Today I decided to play around with WebAssembly for the very first time. So, I wrote this little Fibonacci program in C++:
#include <iostream>
#include <chrono>
int fib(int n) {
if(n==0) {
return 0;
} else if(n==1) {
return 1;
} else {
return fib(n-1) + fib(n-2);
}
}
int main() {
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
int sum = 0;
for (int i = 0; i < 35; ++i) {
sum += fib(i);
}
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> dur = t2 - t1;
std::cout << sum << std::endl;
std::cout << dur.count() << std::endl;
}
And compiled it into Web Assembly
(WA from now onwards) using the following command:
emcc fib.cpp -s WASM=1 -o fib.html
Then, after loading the resulting .html
file into the browser, the output I got was 14930351 592.8
, which means that WA took almost 600 milliseconds
.
Then, I wrote a JS equivalent of the same program, as follows:
export function fib(n) {
return n === 0 ? 0 : (n === 1 ? 1 : fib(n-1) + fib(n-2));
}
export function fibSum(n) {
let sum = 0;
for (let i = 0; i < n; i++) {
sum += fib(i)
}
return sum;
}
I used performance.now()
to measure the elapsed time in milliseconds to calculate fibSum(35)
, which gave an output of 347.200 milliseconds
on Chrome.
I get it that WA is very new hence the compiler must be missing some optimisations as compared to the V8 engine and it takes time to call WA code from the browser and everything but I was not expecting it to be this slow.
Thoughts? Have I not created a proper test case to compare the two?
javascript performance web webassembly
1
Can you please remove all thestd::chrono
stuff andstd::cout
from your code and try again? I made a .js file with the js code you provided and tested it and it took approximately 150ms when I tested it with (node fibjs.js
). Then, I compiled the C code twice: once with the chrono stuff, once without. For the second version, I put the time-measuring code in the generated js file, before and after therun
function. The first compiled version took 300+ms, but the second one took 130-150ms, so very close to the pure js code.
– Adi
Nov 18 at 13:17
So...based on my results, I guess that using a lot of libraries or complex functions also affect the compiled js code.
– Adi
Nov 18 at 13:18
@Adi Can you please guide me where to put that time-measuring code in generatedfib.js
file? I tried removing all thechrono
stuff and putting time-measuring code in therun(args)
method of the generated JS file but no difference.
– Rajat Saxena
Nov 18 at 13:30
1
At the end of the fib.js file, there is a call to the run function:run();
; I analyzed the code and basically that is the entry point of the program. You can use a simpleconsole.time('test'); run(); console.timeEnd('test');
to measure the time.
– Adi
Nov 18 at 14:01
1
You're also not building with optimizations (emcc -O3
or-Os
).
– Veedrac
Nov 19 at 5:05
|
show 2 more comments
up vote
3
down vote
favorite
up vote
3
down vote
favorite
Today I decided to play around with WebAssembly for the very first time. So, I wrote this little Fibonacci program in C++:
#include <iostream>
#include <chrono>
int fib(int n) {
if(n==0) {
return 0;
} else if(n==1) {
return 1;
} else {
return fib(n-1) + fib(n-2);
}
}
int main() {
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
int sum = 0;
for (int i = 0; i < 35; ++i) {
sum += fib(i);
}
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> dur = t2 - t1;
std::cout << sum << std::endl;
std::cout << dur.count() << std::endl;
}
And compiled it into Web Assembly
(WA from now onwards) using the following command:
emcc fib.cpp -s WASM=1 -o fib.html
Then, after loading the resulting .html
file into the browser, the output I got was 14930351 592.8
, which means that WA took almost 600 milliseconds
.
Then, I wrote a JS equivalent of the same program, as follows:
export function fib(n) {
return n === 0 ? 0 : (n === 1 ? 1 : fib(n-1) + fib(n-2));
}
export function fibSum(n) {
let sum = 0;
for (let i = 0; i < n; i++) {
sum += fib(i)
}
return sum;
}
I used performance.now()
to measure the elapsed time in milliseconds to calculate fibSum(35)
, which gave an output of 347.200 milliseconds
on Chrome.
I get it that WA is very new hence the compiler must be missing some optimisations as compared to the V8 engine and it takes time to call WA code from the browser and everything but I was not expecting it to be this slow.
Thoughts? Have I not created a proper test case to compare the two?
javascript performance web webassembly
Today I decided to play around with WebAssembly for the very first time. So, I wrote this little Fibonacci program in C++:
#include <iostream>
#include <chrono>
int fib(int n) {
if(n==0) {
return 0;
} else if(n==1) {
return 1;
} else {
return fib(n-1) + fib(n-2);
}
}
int main() {
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
int sum = 0;
for (int i = 0; i < 35; ++i) {
sum += fib(i);
}
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> dur = t2 - t1;
std::cout << sum << std::endl;
std::cout << dur.count() << std::endl;
}
And compiled it into Web Assembly
(WA from now onwards) using the following command:
emcc fib.cpp -s WASM=1 -o fib.html
Then, after loading the resulting .html
file into the browser, the output I got was 14930351 592.8
, which means that WA took almost 600 milliseconds
.
Then, I wrote a JS equivalent of the same program, as follows:
export function fib(n) {
return n === 0 ? 0 : (n === 1 ? 1 : fib(n-1) + fib(n-2));
}
export function fibSum(n) {
let sum = 0;
for (let i = 0; i < n; i++) {
sum += fib(i)
}
return sum;
}
I used performance.now()
to measure the elapsed time in milliseconds to calculate fibSum(35)
, which gave an output of 347.200 milliseconds
on Chrome.
I get it that WA is very new hence the compiler must be missing some optimisations as compared to the V8 engine and it takes time to call WA code from the browser and everything but I was not expecting it to be this slow.
Thoughts? Have I not created a proper test case to compare the two?
javascript performance web webassembly
javascript performance web webassembly
edited Nov 18 at 12:40
asked Nov 18 at 12:30
Rajat Saxena
1,64023351
1,64023351
1
Can you please remove all thestd::chrono
stuff andstd::cout
from your code and try again? I made a .js file with the js code you provided and tested it and it took approximately 150ms when I tested it with (node fibjs.js
). Then, I compiled the C code twice: once with the chrono stuff, once without. For the second version, I put the time-measuring code in the generated js file, before and after therun
function. The first compiled version took 300+ms, but the second one took 130-150ms, so very close to the pure js code.
– Adi
Nov 18 at 13:17
So...based on my results, I guess that using a lot of libraries or complex functions also affect the compiled js code.
– Adi
Nov 18 at 13:18
@Adi Can you please guide me where to put that time-measuring code in generatedfib.js
file? I tried removing all thechrono
stuff and putting time-measuring code in therun(args)
method of the generated JS file but no difference.
– Rajat Saxena
Nov 18 at 13:30
1
At the end of the fib.js file, there is a call to the run function:run();
; I analyzed the code and basically that is the entry point of the program. You can use a simpleconsole.time('test'); run(); console.timeEnd('test');
to measure the time.
– Adi
Nov 18 at 14:01
1
You're also not building with optimizations (emcc -O3
or-Os
).
– Veedrac
Nov 19 at 5:05
|
show 2 more comments
1
Can you please remove all thestd::chrono
stuff andstd::cout
from your code and try again? I made a .js file with the js code you provided and tested it and it took approximately 150ms when I tested it with (node fibjs.js
). Then, I compiled the C code twice: once with the chrono stuff, once without. For the second version, I put the time-measuring code in the generated js file, before and after therun
function. The first compiled version took 300+ms, but the second one took 130-150ms, so very close to the pure js code.
– Adi
Nov 18 at 13:17
So...based on my results, I guess that using a lot of libraries or complex functions also affect the compiled js code.
– Adi
Nov 18 at 13:18
@Adi Can you please guide me where to put that time-measuring code in generatedfib.js
file? I tried removing all thechrono
stuff and putting time-measuring code in therun(args)
method of the generated JS file but no difference.
– Rajat Saxena
Nov 18 at 13:30
1
At the end of the fib.js file, there is a call to the run function:run();
; I analyzed the code and basically that is the entry point of the program. You can use a simpleconsole.time('test'); run(); console.timeEnd('test');
to measure the time.
– Adi
Nov 18 at 14:01
1
You're also not building with optimizations (emcc -O3
or-Os
).
– Veedrac
Nov 19 at 5:05
1
1
Can you please remove all the
std::chrono
stuff and std::cout
from your code and try again? I made a .js file with the js code you provided and tested it and it took approximately 150ms when I tested it with (node fibjs.js
). Then, I compiled the C code twice: once with the chrono stuff, once without. For the second version, I put the time-measuring code in the generated js file, before and after the run
function. The first compiled version took 300+ms, but the second one took 130-150ms, so very close to the pure js code.– Adi
Nov 18 at 13:17
Can you please remove all the
std::chrono
stuff and std::cout
from your code and try again? I made a .js file with the js code you provided and tested it and it took approximately 150ms when I tested it with (node fibjs.js
). Then, I compiled the C code twice: once with the chrono stuff, once without. For the second version, I put the time-measuring code in the generated js file, before and after the run
function. The first compiled version took 300+ms, but the second one took 130-150ms, so very close to the pure js code.– Adi
Nov 18 at 13:17
So...based on my results, I guess that using a lot of libraries or complex functions also affect the compiled js code.
– Adi
Nov 18 at 13:18
So...based on my results, I guess that using a lot of libraries or complex functions also affect the compiled js code.
– Adi
Nov 18 at 13:18
@Adi Can you please guide me where to put that time-measuring code in generated
fib.js
file? I tried removing all the chrono
stuff and putting time-measuring code in the run(args)
method of the generated JS file but no difference.– Rajat Saxena
Nov 18 at 13:30
@Adi Can you please guide me where to put that time-measuring code in generated
fib.js
file? I tried removing all the chrono
stuff and putting time-measuring code in the run(args)
method of the generated JS file but no difference.– Rajat Saxena
Nov 18 at 13:30
1
1
At the end of the fib.js file, there is a call to the run function:
run();
; I analyzed the code and basically that is the entry point of the program. You can use a simple console.time('test'); run(); console.timeEnd('test');
to measure the time.– Adi
Nov 18 at 14:01
At the end of the fib.js file, there is a call to the run function:
run();
; I analyzed the code and basically that is the entry point of the program. You can use a simple console.time('test'); run(); console.timeEnd('test');
to measure the time.– Adi
Nov 18 at 14:01
1
1
You're also not building with optimizations (
emcc -O3
or -Os
).– Veedrac
Nov 19 at 5:05
You're also not building with optimizations (
emcc -O3
or -Os
).– Veedrac
Nov 19 at 5:05
|
show 2 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53360895%2fwhy-is-webassembly-this-slow-as-compared-to-javascript%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Can you please remove all the
std::chrono
stuff andstd::cout
from your code and try again? I made a .js file with the js code you provided and tested it and it took approximately 150ms when I tested it with (node fibjs.js
). Then, I compiled the C code twice: once with the chrono stuff, once without. For the second version, I put the time-measuring code in the generated js file, before and after therun
function. The first compiled version took 300+ms, but the second one took 130-150ms, so very close to the pure js code.– Adi
Nov 18 at 13:17
So...based on my results, I guess that using a lot of libraries or complex functions also affect the compiled js code.
– Adi
Nov 18 at 13:18
@Adi Can you please guide me where to put that time-measuring code in generated
fib.js
file? I tried removing all thechrono
stuff and putting time-measuring code in therun(args)
method of the generated JS file but no difference.– Rajat Saxena
Nov 18 at 13:30
1
At the end of the fib.js file, there is a call to the run function:
run();
; I analyzed the code and basically that is the entry point of the program. You can use a simpleconsole.time('test'); run(); console.timeEnd('test');
to measure the time.– Adi
Nov 18 at 14:01
1
You're also not building with optimizations (
emcc -O3
or-Os
).– Veedrac
Nov 19 at 5:05