簡體   English   中英

訪問屬性的性能 - 工廠函數 vs. 串聯繼承 vs. 類

[英]Performance of accessing properties - Factory function vs. Concatenative inheritance vs. Class

請幫助:) — 我必須檢查訪問屬性的性能 — 工廠函數、串聯繼承和類,我不明白為什么串聯繼承會丟失? 畢竟,在 Concatenative 繼承中訪問復制的屬性應該是最快的。 我在 Chrome 和 Safari 上運行測試,而 CI 總是失敗。 https://jsperf.com/factory-function-vs-concatenative-inheritance-get

此測試中的代碼:

const alien = {
    sayHello () {
      return `Hello, my name is ${ this.name }`;
    }
  };
  //Delegate prototype
  const createAlienFF = (name) => { 
     return Object.assign(Object.create(alien), {
       name
    });
  }
   //Delegate prototype - creating objects
  var tabFF = [];
  for(var i = 0; i < 1000; i++ ) {
     tabFF[i] = createAlienFF('Clark' + i);
  }

  //Concatenative inheritance
  const createAlienCI = (name) => { 
     return Object.assign( 
      {}, 
      alien, 
      {name: name}
    );
  }
  //Concatenative inheritance - creating objects
  var tabCI = [];
  for(var i = 0; i < 1000; i++ ) {
     tabCI[i] =  createAlienCI("Clark" + i );
  }

  //Class
  class Alien {
    constructor(name) {
      this.name = name
    }
    sayHello() {
      return `Hello, my name is ${ this.name }`;
    }
  }
  //Class - creating objects
  var tabClass = [];
  for(var i = 0; i < 1000; i++ ) {
     tabClass[i] = new Alien("Clark" + i );
  }
  //Tests
  //1 - Delegate prototype
  for(var i = 0; i < 1000; i++ ) {
    tabFF[i].sayHello();
  }

 //2 - Concatenative inheritance
 for(var i = 0; i < 1000; i++ ) {
  tabCI[i].sayHello();
 }

//3 - Class
for(var i = 0; i < 1000; i++ ) {
  tabClass[i].sayHello();
}

畢竟,在 Concatenative 繼承中訪問復制的屬性應該是最快的。

為什么你這么想? 因為是不需要遍歷原型鏈的直接屬性訪問?

嗯,是的,這可能是關於簡單引擎實現的一個很好的推理。 但是你沒有考慮到對象模型的優化是專門為繼承量身定制的,使得對(類)實例的方法訪問非常快。 看看https://github.com/v8/v8/wiki/Design%20Elements#fast-property-accesshttps://blog.ghaiklor.com/optimizations-tricks-in-v8-d284b6c8b183HTTP: //richardartoul.github.io/jekyll/update/2015/04/26/hidden-classes.html和偉大的http://mrale.ph/blog/2012/06/03/explaining-js-vms-in- js-inline-caches.html 要點:V8優化的“已知的形狀”的對象的方法訪問,也就是從繼承對象alienAlien.prototype你的情況(它們共享相同的隱藏的類)。 知道猜測在你的循環中,只使用了那個形狀的對象,並且可以推斷出它們都調用了完全相同的sayHello函數。 這是一個可以從中獲取代碼的固定位置,可以進行進一步的優化,例如內聯。 另一方面,由createAlienCI工廠創建的對象也都共享相同的形狀,但每個對象都包含其單獨的sayHello屬性。 所有這些屬性可能都包含相同的函數對象,但我們無法知道(我們也不會猜到——這是一種不尋常的模式)。 因此,引擎每次在調用之前都會從每個實例中獲取函數引用 - 至少它知道每個實例的位置(在哪個內存偏移處),因為它們的形狀不變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM