Proxies and the Reflect functions are implemented in C++ which means that 
currently there are two things that will cause a slowdown over the simple 
delegator object that installs getters and setters:
1. the optimizing compiler cannot inline or otherwise improve calls to 
proxies
2. calls to proxies will always be more costly since we have to jump from 
the JavaScript world to the C++ world

A minor difference from the nodes delegates is that you do a full-blown 
[[HasProperty]] check with Reflect.has (which walks up the prototype 
chain), while in the delegates implementation you only check this once if 
you use the auto-setup.
If you care a bit less for some corner cases you can do a keyed-load from 
the target (target[key]) and just assume that if it's undefined you have to 
look it up on origin object.

let me know if this helps.

On Friday, August 5, 2016 at 6:49:09 AM UTC+2, Fangdun Cai wrote:
>
>
>    - Node 6.3.1:
>    - macOS:
>
> I try use proxies for my project and created the 
> https://github.com/fundon/delegate-proxy.
>
> But results from the benchmarks, proxy is very slowly. 
>
> How to improve it?
> Source code
>
> module.exports = function delegateProxy (target, origin) {
>   return new Proxy(target, {
>     get (target, key, receiver) {
>       if (Reflect.has(target, key)) return Reflect.get(target, key, receiver)
>       const value = origin[key]
>       return 'function' === typeof value ? function method () {
>         return value.apply(origin, arguments)
>       } : value
>     },
>     set (target, key, value, receiver) {
>       if (Reflect.has(target, key)) return Reflect.set(target, key, value, 
> receiver)
>       origin[key] = value
>       return true
>     }
>   })
> }
>
> Benchmarks code, delegate-proxy VS delegates
>
> const Benchmark = require('benchmark')const delegate = 
> require('delegates')const delegateProxy = require('..')
> const obj = {}
> const p1 = {}const d1 = delegateProxy(p1, obj)
> const d0 = {}d0.obj = objconst d = delegate(d0, 'obj')
> for (let i = 0, l = 1000; i < l; i++) {
>   obj[`a${i}`] = i
>   obj[`b${i}`] = function () {}
>   obj[`c${i}`] = i
>   d.getter(`a${i}`)
>   d.method(`b${i}`)
>   d.access(`c${i}`)
> }
> const suite = new Benchmark.Suite()
>
> suite
>   .add('delegates#getter', () => {
>     /* eslint no-unused-expressions: 0 */
>     d0.a0 === 0 ? 1 : 0
>   })
>   .add('delegateProxy#getter', () => {
>     /* eslint no-unused-expressions: 0 */
>     d1.a0 === 0 ? 1 : 0
>   })
>   .on('cycle', event => {
>     console.log(String(event.target))
>   })
>   .on('complete', function () {
>     console.log('Fastest is ' + this.filter('fastest').map('name'))
>   })
>   .run()
> const suite2 = new Benchmark.Suite()
>
> suite2
>   .add('delegates#method', () => {
>     d0.b0()
>   })
>   .add('delegateProxy#method', () => {
>     d1.b0()
>   })
>   .on('cycle', event => {
>     console.log(String(event.target))
>   })
>   .on('complete', function () {
>     console.log('Fastest is ' + this.filter('fastest').map('name'))
>   })
>   .run()
> const suite3 = new Benchmark.Suite()
>
> suite3
>   .add('delegates#access', () => {
>     d0.c0 = 1
>   })
>   .add('delegateProxy#access', () => {
>     d1.c0 = 1
>   })
>   .on('cycle', event => {
>     console.log(String(event.target))
>   })
>   .on('complete', function () {
>     console.log('Fastest is ' + this.filter('fastest').map('name'))
>   })
>   .run()
> const suite4 = new Benchmark.Suite()
>
> suite4
>   .add('Reflect#get', () => {
>     Reflect.get(obj, 'a0')
>   })
>   .add('obj#key', () => {
>     /* eslint dot-notation: 0 */
>     obj['a0']
>   })
>   .add('obj.key', () => {
>     obj.a0
>   })
>   .on('cycle', event => {
>     console.log(String(event.target))
>   })
>   .on('complete', function () {
>     console.log('Fastest is ' + this.filter('fastest').map('name'))
>   })
>   .run()
> const suite5 = new Benchmark.Suite()
>
> suite5
>   .add('Reflect#has', () => {
>     Reflect.has(d0, 'a0')
>   })
>   .add('key in d0', () => {
>     'a0' in d0
>   })
>   .on('cycle', event => {
>     console.log(String(event.target))
>   })
>   .on('complete', function () {
>     console.log('Fastest is ' + this.filter('fastest').map('name'))
>   })
>   .run()
> const suite6 = new Benchmark.Suite()
>
> suite6
>   .add('Reflect#set', () => {
>     Reflect.set(obj, 'a0', 2)
>   })
>   .add('obj#key=', () => {
>     /* eslint dot-notation: 0 */
>     obj['a0'] = 2
>   })
>   .on('cycle', event => {
>     console.log(String(event.target))
>   })
>   .on('complete', function () {
>     console.log('Fastest is ' + this.filter('fastest').map('name'))
>   })
>   .run()
>
> Results
>
> delegates#getter x 2,414,206 ops/sec ±0.81% (83 runs sampled)
> delegateProxy#getter x 1,383,270 ops/sec ±0.94% (84 runs sampled)
> Fastest is delegates#getter
> delegates#method x 4,707,516 ops/sec ±6.25% (53 runs sampled)
> delegateProxy#method x 1,339,755 ops/sec ±6.93% (65 runs sampled)
> Fastest is delegates#method
> delegates#access x 2,427,859 ops/sec ±8.88% (67 runs sampled)
> delegateProxy#access x 1,344,403 ops/sec ±10.72% (47 runs sampled)
> Fastest is delegates#access
> Reflect#get x 7,481,142 ops/sec ±2.35% (82 runs sampled)
> obj#key x 35,676,972 ops/sec ±0.73% (83 runs sampled)
> obj.key x 35,687,692 ops/sec ±0.65% (82 runs sampled)
> Fastest is obj.key,obj#key
> Reflect#has x 8,369,451 ops/sec ±4.04% (77 runs sampled)
> key in d0 x 10,618,353 ops/sec ±7.39% (51 runs sampled)
> Fastest is key in d0
> Reflect#set x 6,356,287 ops/sec ±7.22% (56 runs sampled)
> obj#key= x 32,970,782 ops/sec ±1.74% (82 runs sampled)
> Fastest is obj#key=
>
>

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to