I wouldn't say it's due to current implementation details. The
specification for most Proxy operations just demands very complicated (and
therefore slow) internal workflows. In performance-sensitive code, it's
probably better to avoid using Proxies -- usually the same functionality
can also be achieved using faster techniques (for example, your snippet
looks like you could just put |origin| onto |target|'s prototype chain).

On Fri, Aug 5, 2016 at 10:21 AM, <cbr...@chromium.org> wrote:

> 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.
>

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