Are arrow functions faster (more performant, lighter) than ordinary standalone function declaration in v8?

后端 未结 5 1544
太阳男子
太阳男子 2020-12-01 04:42

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) =>          


        
相关标签:
5条回答
  • 2020-12-01 05:23

    V8 developer here. Arrow functions are (mostly) just "syntactic sugar" for conventional function declarations. There is no performance difference.

    0 讨论(0)
  • 2020-12-01 05:31

    in my exp I have found that arrow functions do run faster than normal JS functions. Here is a small snippet in react which uses arrow and normal function. I found that the component using arrow functions runs a bit faster than the one having normal js function.

    https://codepen.io/lokeshpathrabe/pen/qgzadx

    class Fun extends React.Component {
    
      constructor(props){
        super(props);
        this.state = {start: new Date().getTime(),
                     end: new Date().getTime(),
                     number: 0};
        console.log('Function start: ', this.state.start);
        const fun = function(me){
          let n = me.state.number
          me.setState({
            ...me.state, end: new Date().getTime(), number: ++n
          })
        }
        this.interval = setInterval(fun, 1, this);
      }
    
      stop(){
        clearInterval(this.interval);
      }
    
      componentDidUpdate(){
        if((this.state.end - this.state.start) > 5000){
          console.log('Function end: ', this.state.end);
          clearInterval(this.interval)
        }
      }
    
      render() {
        return (
          <div>
            <h2>Counter with Function {this.state.number}</h2>
          </div>
        )
      }
    }
    
    class Arrow extends React.Component {
    
      constructor(props){
        super(props);
        this.state = {start: new Date().getTime(),
                     end: new Date().getTime(),
                     number: 0};
        console.log('Arrow start: ', this.state.start);
        this.interval = setInterval(()=>{
          let n = this.state.number
          this.setState({
            ...this.state, end: new Date().getTime(), number: ++n
          })
        }, 1);
      }
    
      stop(){
        clearInterval(this.interval);
      }
    
      componentDidUpdate(){
        if((this.state.end - this.state.start) > 5000){
          console.log('Arrow end: ', this.state.end);
          clearInterval(this.interval)
        }
      }
    
      render() {
        return (
          <div>
            <h2>Counter with Arrow {this.state.number}</h2>
          </div>
        )
      }
    }
    
    class HOC extends React.Component {
    
      render() {
    
        return (<div>
            <h1>The one reaching higher count wins</h1>
            <Arrow/>
            <Fun/>
            </div>);
      }
    }
    
    ReactDOM.render(<HOC />, document.getElementById('react-content'))
    

    Do let me know if your opinion differ

    0 讨论(0)
  • 2020-12-01 05:37

    The following shows that:

    1. There is a penalty for going first (either traditional or fat)
    2. There is no discernible difference in Chrome

    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>

    0 讨论(0)
  • 2020-12-01 05:46

    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.

    0 讨论(0)
  • 2020-12-01 05:49

    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.

    0 讨论(0)
提交回复
热议问题