最近的Chrome / V8版本中的对象描述符getter / setter性能 [英] Object descriptor getter/setter performance in recent Chrome/V8 versions
问题描述
var obj = {};
var _a = 1;
obj._a = 1;
obj.aGetter = function(){
return _a;
}
obj.aSetter = function(val){
_a = val;
Object.defineProperty(obj,'a',{
enumerable:true,
get:function(){
return _a;
},
set:function(val){
_a = val;
}
});
使用getter / setter函数
obj.aSetter(2);
obj.aGetter();与直接媒体访问相比,
的Chrome / V8性能有所下降(约3倍):
obj._a = 2;
obj._a;
这是可以理解的。并使用描述符getter / setter
obj.a = 2;
obj.a;
会导致Chrome浏览器的性能降低30倍左右(41至最新)几乎和代理
一样慢。虽然Firefox和旧版本的Chrome浏览器版本使用描述符getter / setter,但是性能不会有太大的损失。
最近Chrome / V8版本中描述符getter / setter性能的确切问题是什么?这是一个可以被监控的已知问题吗?
这些测量是使用Benchmark.js(jsPerf引擎)完成的。我无法提供jsPerf测试的链接来显示差异,因为jsPerf已经被其反DDoS措施严重搞砸了,但我确信现有的测试可以证明这一点。 p>
性能变化与这个Chromium问题(积分转到@VyacheslavEgorov)。
为了避免性能问题,应该使用原型。这是类可能用于实例化对象一次的几个原因之一。
使用ES5:
var _a = 1;
函数Obj(){}
Object.defineProperty(Obj.prototype,'a',{
enumerable:true,
get:function (){
return _a;
},
set:function(val){
_a = val;
}
});
var obj = new Obj();
//或
var obj = Object.create(Obj.prototype);
或者使用ES6语法糖:
class Obj {
constructor(){
this._a = 1;
}
get a(){
return this._;
}
set a(val){
this._a = val;
}
}
let obj = new Obj();
Given
var obj = {};
var _a = 1;
obj._a = 1;
obj.aGetter = function() {
return _a;
}
obj.aSetter = function(val) {
_a = val;
}
Object.defineProperty(obj, 'a', {
enumerable: true,
get: function () {
return _a;
},
set: function(val) {
_a = val;
}
});
using getter/setter functions
obj.aSetter(2);
obj.aGetter();
will have some decrease in Chrome/V8 performance (~3x) when compared to direct property access:
obj._a = 2;
obj._a;
This is be understandable. And using descriptor getter/setter
obj.a = 2;
obj.a;
will cause ~30x decrease in Chrome (41 to latest) performance - almost as slow as Proxy
. While Firefox and older Chrome versions use descriptor getter/setter with no significant performance penalty.
What is the exact problem with descriptor getter/setter performance in recent Chrome/V8 versions? Is it a known issue that can be monitored?
The measurements were done with Benchmark.js (jsPerf engine). I'm unable to provide a link to jsPerf test to visualize the difference because jsPerf has been seriously screwed up with its anti-DDoS measures, but I'm sure there are existing ones that can prove a point.
The changes in performance are relevant to this Chromium issue (credits go to @VyacheslavEgorov).
To avoid performance issues, a prototype should be used instead. This is one of few reasons why classes may be used to instantiate an object once.
With ES5:
var _a = 1;
function Obj() {}
Object.defineProperty(Obj.prototype, 'a', {
enumerable: true,
get: function () {
return _a;
},
set: function(val) {
_a = val;
}
});
var obj = new Obj();
// or
var obj = Object.create(Obj.prototype);
Or with ES6 syntactic sugar:
class Obj {
constructor() {
this._a = 1;
}
get a() {
return this._a;
}
set a(val) {
this._a = val;
}
}
let obj = new Obj();
这篇关于最近的Chrome / V8版本中的对象描述符getter / setter性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!