Class-based vs function-based Proxy

Benchmark created on


Description

Which one works faster:

  • Lazy property accessor made with function and Proxy;
  • or one made with class and Proxy?

Setup

function FuncLazy(keys, value_func, allow_unset_keys = false) {
    // ...
    const obj = Object.create(null)     // this one is holding values
    for (const key of keys)   obj[key] = undefined

    function get(_target, property, _receiver) {
        if (!(property in obj) && !allow_unset_keys) {
            throw new Error(`undefined key '${String(property)}'`)
        }

        if (obj[property] === undefined) {
            obj[property] = value_func(property)
        }

        return obj[property]
    }

    return new Proxy(obj, {get: get})
}


class ClassLazy {
    obj = Object.create(null)     // this one is holding values

    constructor(keys, value_func, allow_unset_keys = false) {
        for (const key of keys) {
            this.obj[key] = undefined
        }

        this.__func = value_func
        this.__allow_unset_keys = allow_unset_keys

        this.proxy = new Proxy(this.obj, this)
    }

    get(_target, property, _receiver) {
        if (!(property in this.obj) && !this.__allow_unset_keys) {
            throw new Error(`undefined key '${String(property)}'`)
        }

        if (this.obj[property] === undefined) {
            this.obj[property] = this.__func(property)
        }

        return this.obj[property]
    }
}



const keys = []
for (let i = 0; i < 10000; i++)  keys[i] = `key${i}`

const pure = Object.create(null)
for (const key of keys)   pure[key] = undefined

const keyfunc = (k) => `**${k}**`


const cl = new ClassLazy(keys, keyfunc)
const c_lazy = cl.proxy

const f_lazy = FuncLazy(keys, keyfunc)

Test runner

Ready to run.

Testing in
TestOps/sec
Func lazy
const vals = {}

for (const k of Object.keys(f_lazy)) {
	vals[k] = f_lazy[k]
}
ready
Class lazy
const vals = {}

for (const k of Object.keys(c_lazy)) {
	vals[k] = c_lazy[k]
}
ready
Pure (with no lazy)
const vals = {}

for (const k of Object.keys(pure)) {
	vals[k] = keyfunc(k)
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.