为什么如果道具数大于8,NodeJS对象创build的性能如此糟糕?

我想知道当创build一个具有8个以上属性的对象时,NodeJS是否有任何限制? 我做了一个基准testing,看起来如果对象有8个以上属性,性能会很差。

testing套件: https : //github.com/icebob/js-perf-benchmark/blob/master/suites/properties.js (问题结束时的完整副本)

结果:

  • 创build1道具0%(62,695,620 rps)(平均15ns)
  • 用8-prop-31.95%(42,662,752 rps)(平均23ns)
  • 创build对象9 prop -95.79%(2,640,046 rps) (平均:378ns)

码:

bench.add("Create object with 8 prop", () => { let opts = { prop1: 5, prop2: "", prop3: false, prop4: 1, prop5: 0, prop6: null, prop7: "Hello", prop8: 12345 }; return opts; }); bench.add("Create object with 9 prop", () => { let opts = { prop1: 5, prop2: "", prop3: false, prop4: 1, prop5: 0, prop6: null, prop7: "Hello", prop8: 12345, prop9: "asd" }; return opts; }); 

环境:

  • Windows_NT 6.1.7601 x64
  • Node.JS: 6.9.5
  • V8: 5.1.281.89
  • 英特尔(R)酷睿TM i5-2400 CPU @ 3.10GHz×4

以下是上面链接的testing套件的内容:

 "use strict"; let Benchmarkify = require("benchmarkify"); let benchmark = new Benchmarkify("Object properties").printHeader(); let bench = benchmark.createSuite("Create object with many properties"); // ---- bench.add("Create object with 1 prop", () => { let opts = { prop1: 5 }; return opts; }); bench.add("Create object with 8 prop", () => { let opts = { prop1: 5, prop2: "", prop3: false, prop4: 1, prop5: 0, prop6: null, prop7: "Hello", prop8: 12345 }; return opts; }); bench.add("Create object with 9 prop", () => { let opts = { prop1: 5, prop2: "", prop3: false, prop4: 1, prop5: 0, prop6: null, prop7: "Hello", prop8: 12345, prop9: "asd" }; return opts; }); bench.add("Create object with 20 prop", () => { let opts = { prop1: 5, prop2: "", prop3: false, prop4: 1, prop5: 0, prop6: null, prop7: "Hello", prop8: 12345, prop9: "asd", prop10: false, prop11: 5, prop12: "", prop13: false, prop14: 1, prop15: 0, prop16: null, prop17: "Hello", prop18: 12345, prop19: "asd", prop20: false }; return opts; }); bench.run(); 

据我所知 – 是的。

v8引擎中的对象有两个对象表示forms:

  • 快速道具的数量有限
  • 缓慢的无限道具

对于新对象,V8引擎默认为“FAST 8属性对象”分配内存,这应该覆盖大多数用例。

如果物业的数量超过这个限制 – 重build对象到更多的慢速forms,但允许有无限数量的道具里面。

顺便说一句,这与新的对象实例化(如new X() )无关:从V8引擎重新计算新对象(每个类/内部types)道具的数量。 所以如果你的代码创build了复杂的类,引擎将会默认为这个类/内部types开始创build更多属性的FAST对象。


certificate:

V8引擎的内存pipe理细节可以在这里findhttp://jayconrod.com/posts/52/a-tour-of-v8-object-representation

对于没有类构造的新对象(如var a = {} ) – 所有属性都转到固定数组,在文章“Extra properties”

引擎默认为固定数组中的8个元素分配空间

固定数组满后 – 对象在这里重build成字典

原型和系统对象总是FAST,当固定数组已满时,它们使用不同的重build过程 。