I am asking this question because I and my colleague have a dispute on coding style because he prefers arrows function declaration:
const sum = (a, b) => a + b;
And I prefer old-style standalone function declaration:
function sum(a, b) {
return a + b;
}
My point is that code in old-style more readable and you can more clearly distinguish function and variable declarations. His point is that code with arrow functions just run faster.
Do you know something about actual performance penalties (in v8) when you use old-style standalone function declaration instead of arrow functions? Are that penalties really exists?
His point is that code with arrow functions just run faster.
Function expressions are best for object methods. Arrow functions are best for callbacks or methods like map , reduce , or forEach . Use function declarations for functions you'd call by name (because they're hoisted). Use arrow functions for callbacks (because they tend to be terser).
There are two major benefits of using Arrow functions. One is that it's a shorter syntax and thus requires less code. The main benefit is that it removes the several pain points associated with the this operator.
An Arrow function should not be used as methods. An arrow function can not be used as constructors. An arrow function can not use yield within its body. Arrow function cannot be suitable for call apply and bind methods.
V8 developer here. Arrow functions are (mostly) just "syntactic sugar" for conventional function declarations. There is no performance difference.
The following shows that:
function goFat() {
for (var i = 0; i < 1000000; i++) {
var v = ()=>{};
v();
}
}
function goTraditional() {
for (var i = 0; i < 1000000; i++) {
var v = function() {};
v();
}
}
function race() {
var start = performance.now();
goTraditional();
console.log('Traditional elapsed: ' + (performance.now() - start));
start = performance.now();
goFat()
console.log('Fat elapsed: ' + (performance.now() - start));
start = performance.now();
goTraditional();
console.log('Traditional elapsed: ' + (performance.now() - start));
start = performance.now();
goFat()
console.log('Fat elapsed: ' + (performance.now() - start));
console.log('------');
}
<button onclick="race()">RACE!</button>
I think arrow functions in class properties might cause some performance issue. Here is an example :
class Car {
setColor = (color) => { this.color = color; }
constructor() {
this.color = '';
this.getColor = () => { return this.color; };
}
printCarColor() {
console.log(this.color);
}
}
var c = new Car();
console.log(c);
If we take a look at the variable c you will notice that function setColor and getColor are created brand new for each instance, and each new copy is placed on each instance whereas function printCarColor is residing on the prototype.
If you want a thousand instances to each be able to make fixed-context method references, you're going to need a thousand separate methods (not one shared), and of course then you're going to have to store each of those thousand separate methods on the instances themselves, thereby defeating the whole point of the single shared prototype.
I made a short benchmark in jsben.ch. I ran it many times it seems that arrow functions were in the most cases just tiny little bit faster than normal functions. Even once or twice normal function was faster... It looks like the difference is insignificant. So in short - if you don't need to mind context or this, just use whatever looks better for you ;)
https://jsben.ch/kJxPT
const a = (b, c) => b+c;
a(1,2);
VS
function a(b,c){
return b+c;
}
a(1,2);
There are two examples for nodejs:
function testFat(a, b) {
return a + b;
}
let testArrow = (a, b) => a + b;
let t1 = process.hrtime();
let tmp1 = 0;
for (let i = 0; i < 1000000000; ++i) {
tmp1 = testFat(tmp1, i);
}
var fatTime = process.hrtime(t1);
console.log('fat', fatTime);
let t2 = process.hrtime();
let tmp2 = 0;
for (let i = 0; i < 1000000000; ++i) {
tmp2 = testArrow(tmp2, i);
}
var arrowTime = process.hrtime(t2);
console.log('arrow', arrowTime);
function testFat() {
return 0;
}
let testArrow = () => 0;
let t1 = process.hrtime();
for (let i = 0; i < 1000000000; ++i) {
testFat();
}
var fatTime = process.hrtime(t1);
console.log('fat', fatTime);
let t2 = process.hrtime();
for (let i = 0; i < 1000000000; ++i) {
testArrow();
}
var arrowTime = process.hrtime(t2);
console.log('arrow', arrowTime);```
Results are:
bash-3.2$ node test_plus_i.js
fat [ 0, 931986419 ]
arrow [ 0, 960479009 ]
bash-3.2$ node test_zero.js
fat [ 0, 479557888 ]
arrow [ 0, 478563661 ]
bash-3.2$ node --version
v12.8.0
bash-3.2$
So you can see that there is no difference in function call overhead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With