最近的Chrome / V8版本中的对象描述符getter / setter性能 [英] Object descriptor getter/setter performance in recent Chrome/V8 versions

查看:142
本文介绍了最近的Chrome / V8版本中的对象描述符getter / setter性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆