最近 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;
将导致 ~30 倍的 Chrome(41 到最新)性能下降 - 几乎与 Proxy
一样慢。虽然 Firefox 和更早的 Chrome 版本使用描述符 getter/setter 而没有显着的性能损失。
在最近的 Chrome/V8 版本中,描述符 getter/setter 性能的确切问题是什么?这是一个可以监控的已知问题吗?
测量是使用 Benchmark.js(jsPerf 引擎)完成的。我无法为 jsPerf 测试提供 link 以可视化差异,因为 jsPerf 的反 DDoS 措施已经严重搞砸了,但我确信现有的措施可以证明这一点。
性能变化与this Chromium issue相关(致谢@VyacheslavEgorov)。
为避免性能问题,应改用原型。这是为什么可以使用单例 类 来实例化一个对象一次的少数几个原因之一。
使用 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);
或者使用 ES6 语法糖:
class Obj {
constructor() {
this._a = 1;
}
get a() {
return this._a;
}
set a(val) {
this._a = val;
}
}
let obj = new Obj();
给定
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;
将导致 ~30 倍的 Chrome(41 到最新)性能下降 - 几乎与 Proxy
一样慢。虽然 Firefox 和更早的 Chrome 版本使用描述符 getter/setter 而没有显着的性能损失。
在最近的 Chrome/V8 版本中,描述符 getter/setter 性能的确切问题是什么?这是一个可以监控的已知问题吗?
测量是使用 Benchmark.js(jsPerf 引擎)完成的。我无法为 jsPerf 测试提供 link 以可视化差异,因为 jsPerf 的反 DDoS 措施已经严重搞砸了,但我确信现有的措施可以证明这一点。
性能变化与this Chromium issue相关(致谢@VyacheslavEgorov)。
为避免性能问题,应改用原型。这是为什么可以使用单例 类 来实例化一个对象一次的少数几个原因之一。
使用 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);
或者使用 ES6 语法糖:
class Obj {
constructor() {
this._a = 1;
}
get a() {
return this._a;
}
set a(val) {
this._a = val;
}
}
let obj = new Obj();