日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

ES6 Proxy 性能之我见

發布時間:2023/11/27 生活经验 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ES6 Proxy 性能之我见 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ES6 Proxy 性能之我見

本文翻譯自https://thecodebarbarian.com/thoughts-on-es6-proxies-performance

Proxy是ES6的一個強力功能,它通過為 get/set一個屬性 設置"陷阱"(函數處理器)讓我們可以攔截對于對象屬性的操作。比如:

const obj = {};
const proxy = new Proxy(obj, {get: () => {console.log('hi');}
});obj.a; // "hi"

Proxy被稱贊為現在已經被廢棄的Object.observe()屬性的取代者。

然而不幸的是,Proxy有一個致命缺陷:性能。

更打擊人的是,Object.observe()就是因為性能被廢棄的,而以我(原作者)對V8的理解,對于JIT(Just in Time,準時制)來說,Object.observe()比Proxy容易優化多了。

Proxy到底有多慢?

我(原作者)在node v6.9.0中用benchmark簡單試了一下:

var Benchmark = require('benchmark');var suite = new Benchmark.Suite;var obj = {};var _obj = {};
var proxy = new Proxy(_obj, {set: (obj, prop, value) => { _obj[prop] = value; }
});var defineProp = {};
Object.defineProperty(defineProp, 'prop', {configurable: false,set: v => defineProp._v = v
});// 譯者注: vanilla js 指的就是原生js
suite.add('vanilla', function() {obj.prop = 5;}).add('proxy', function() {proxy.prop = 5;}).add('defineProperty', function() {defineProp.prop = 5;}).on('cycle', function(event) {console.log(String(event.target));}).on('complete', function() {console.log('Fastest is ' + this.filter('fastest').map('name'));}).run();

結果如下:

$ node proxy.js
vanilla x 74,288,023 ops/sec ±0.78% (86 runs sampled)
proxy x 3,625,152 ops/sec ±2.51% (86 runs sampled)
defineProperty x 74,815,513 ops/sec ±0.80% (85 runs sampled)
Fastest is defineProperty,vanilla
$

從這個簡單的benchmark中我們可以看到,Proxy的set 比直接賦值和defineProperty慢非常多(譯者注:ops/sec,每秒進行的操作數,越大越快)。

為防大家好奇,我(原作者)又在node 4.2.1測試了一下Object.observe()

$ node proxy.js
vanilla x 78,615,272 ops/sec ±1.55% (84 runs sampled)
defineProperty x 79,882,188 ops/sec ±1.31% (85 runs sampled)
Object.observe() x 5,234,672 ops/sec ±0.86% (89 runs sampled)
Fastest is defineProperty,vanilla

有些文章可能讓你覺得只要Proxy不用get/set而是只設置getOwnPropertyDescriptor()的話,就比其他的快,于是我(原作者)又試了試:

var _obj = {};
var propertyDescriptor = {configurable: true,set: v => { _obj.prop = v; }
};
var proxy = new Proxy(_obj, {getOwnPropertyDescriptor: (target, prop) => propertyDescriptor
});

不幸的是,反而更慢了:

$ node proxy.js
vanilla x 73,695,484 ops/sec ±1.04% (88 runs sampled)
proxy x 2,026,006 ops/sec ±0.74% (90 runs sampled)
defineProperty x 74,137,733 ops/sec ±1.25% (88 runs sampled)
Fastest is defineProperty,vanilla
$

用Proxy包裹一個函數并調用同樣比原生的包裹函數并調用慢非常多:

var Benchmark = require('benchmark');var suite = new Benchmark.Suite;var fn = () => 5;
var proxy = new Proxy(function() {}, {apply: (target, context, args) => fn.apply(context, args)
});var wrap = () => fn();// add tests
suite.add('vanilla', function() {fn();}).add('proxy', function() {proxy();}).add('wrap', function() {wrap();}).on('cycle', function(event) {console.log(String(event.target));}).on('complete', function() {console.log('Fastest is ' + this.filter('fastest').map('name'));}).run();
$ node proxy2.js
vanilla x 78,426,813 ops/sec ±0.93% (88 runs sampled)
proxy x 5,244,789 ops/sec ±2.17% (87 runs sampled)
wrap x 75,350,773 ops/sec ±0.85% (85 runs sampled)
Fastest is vanilla

無用的提升Proxy性能的方法

目前最有影響力的提升Proxy性能的方法是讓被修改的屬性的configurable設為false:

var _obj = {};
Object.defineProperty(_obj, 'prop', { configurable: false });
var propertyDescriptor = {configurable: false,enumerable: true,set: v => { _obj.prop = v; }
};
var proxy = new Proxy(_obj, {getOwnPropertyDescriptor: (target, prop) => propertyDescriptor
});

(譯者注:這段代碼有些問題,enumerableconfigurable為false時是無效的)

$ node proxy.js
vanilla x 74,622,163 ops/sec ±0.95% (85 runs sampled)
proxy x 4,649,544 ops/sec ±0.47% (85 runs sampled)
defineProperty x 77,048,878 ops/sec ±0.60% (88 runs sampled)
Fastest is defineProperty
$

要是這樣寫set/get,還不如直接用 Object.defineProperty()

這樣寫的話,你就不得不設置每個你要在Proxy中用到的屬性不可配置(not configurable)。

不然的話,V8就會報錯:

var _obj = {};
Object.freeze(_obj);
var propertyDescriptor = {configurable: false,enumerable: true,set: v => { _obj.prop = v; }
};
var proxy = new Proxy(_obj, {getOwnPropertyDescriptor: (target, prop) => propertyDescriptor
});// Throws:
// "TypeError: 'getOwnPropertyDescriptor' on proxy: trap returned
// descriptor for property 'prop' that is incompatible with the
// existing property in the proxy target"
// 攔截'prop'屬性返回的descriptor和target(原對象)已經存在的屬性不匹配
proxy.prop = 5;

Proxy 也要不行了么?

Proxy比 Object.defineProperty()有不少優點:

  • Proxy 可以嵌套,而Object.defineProperty()getter/setter就不能嵌套,這樣你就不需要知道提前知道你要攔截的所有屬性
  • 可以攔截數組變化

但它性能太差了。

性能有多大影響呢?

以Promise和回調為例:

var Benchmark = require('benchmark');var suite = new Benchmark.Suite;var handleCb = cb => cb(null);// add tests
suite.add('new function', function() {handleCb(function(error, res) {});}).add('new promise', function() {return new Promise((resolve, reject) => {});}).add('promise resolve', function() {Promise.resolve().then(() => {});}).on('cycle', function(event) {console.log(String(event.target));}).on('complete', function() {console.log('Fastest is ' + this.filter('fastest').map('name'));}).run();
$ node promise.js
new function x 26,282,805 ops/sec ±0.74% (90 runs sampled)
new promise x 1,953,037 ops/sec ±1.02% (86 runs sampled)
promise resolve x 194,173 ops/sec ±13.80% (61 runs sampled)
Fastest is new function
$

Promise也慢了非常多,

但是 bluebird聲稱為Promise提供"非常好的性能",測試一下:

$ node promise.js
new function x 26,986,342 ops/sec ±0.48% (89 runs sampled)
new promise x 11,157,758 ops/sec ±1.05% (87 runs sampled)
promise resolve x 671,079 ops/sec ±27.01% (18 runs sampled)
Fastest is new function

雖然快了很多,但仍然比回調慢不少。

所以我們要因此放棄Promise么?

并不是這樣的,很多公司仍然選擇了使用Promise。我(原作者)雖然不是很確定,但是Uber好像就在使用Promise。

結論

Proxy很慢,但是在你因其性能而放棄它之前,記得同樣性能很差的Promise在最近幾年中被快速采用。

如果你想使用代理,很可能你不會感覺到性能的影響,除非你發現自己為了性能的原因改變了Promise庫(或者完全避開了它們)。

更新

2019.01, 在node v11.3.0中: Promise已經變得足夠好, Proxy還是那樣

vanilla x 833,244,386 ops/sec ±0.76% (89 runs sampled)
proxy x 28,590,800 ops/sec ±0.72% (88 runs sampled)
wrap x 824,349,552 ops/sec ±0.87% (86 runs sampled)
Fastest is vanilla,wrap
new function x 834,121,566 ops/sec ±0.82% (89 runs sampled)
new promise x 819,789,350 ops/sec ±0.76% (87 runs sampled)
promise resolve x 1,212,009 ops/sec ±40.98% (30 runs sampled)
Fastest is new function

轉載于:https://www.cnblogs.com/zmj97/p/10954968.html

總結

以上是生活随笔為你收集整理的ES6 Proxy 性能之我见的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。