Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

hasOwnProperty performance issue #9130

Closed
ghominejad opened this issue Feb 2, 2015 · 7 comments
Closed

hasOwnProperty performance issue #9130

ghominejad opened this issue Feb 2, 2015 · 7 comments

Comments

@ghominejad
Copy link

When i call hasOwnProperty some times has good performance and some times 20x slower. for example when i run it 5 times, then 2 times become very slow but 3 times is fast!!! but when i don't use hasOwnProperty then my code always has good performance!

codes :

var cacheobj = {};

console.time('set');
for(var i = 0; i <= 1000000; i++) {
    cacheobj[i + ' a long key a long key '] = i;
}

console.timeEnd('set');
console.time('get');

var val = 0;
for(var i = 0; i <= 1000000; i++) {
    if(cacheobj.hasOwnProperty(i + ' a long key a long key ')) {
        val = cacheobj[i + ' a long key a long key '];
    }
}
console.timeEnd('get');
@ghominejad
Copy link
Author

in my real test i generated string keys to avoiding using integer conversion and i sometimes had 25x slower results

var cacheobj = {};
var keys = [];

for(var i = 0; i <= 1000000; i++) {
    keys.push(i + ' a long string key a long string key ');
}

console.time('set');
for(var i = 0; i <= 1000000; i++) {
    var key = keys[i];
    cacheobj[key] = i;
}
console.timeEnd('set');

console.time('get');
var val=0;
for(var i = 0; i <= 1000000; i++) {
    var key = keys[i];
    if(cacheobj.hasOwnProperty(key)) {
        val = cacheobj[key];
    }
}
console.timeEnd('get');

results :
set: 1384ms
get: 372ms

set: 1355ms
get: 9043ms

set: 1472ms
get: 9060ms

set: 1445ms
get: 375ms

set: 1351ms
get: 373ms

@sudheer594
Copy link

Surprisingly,
Changing cacheobj.hasOwnProperty(key) to Object.prototype.hasOwnProperty.call(cacheobj,key) improves the situation.

results:

set: 2153ms
get: 674ms
set: 2165ms
get: 703ms
set: 2243ms
get: 975ms
set: 2257ms
get: 641ms
set: 2539ms
get: 659ms

Though , In browser environments cacheobj.hasOwnPropery is working efficiently.

@sudheer594
Copy link

If the cacheObj purpose to be a key value pair , we can avoid using objects and instead create a map like this.

function createMap()
    {
        function map(){}
        map.prototype = Object.create(null);

        return new map();
    }

using the createMap method is useful, since you dont have to worry about prototype properties.
Correct me if i am wrong.
referred from https://github.com/shichuan/javascript-patterns

@ghominejad
Copy link
Author

Thank you very much, Object.prototype.hasOwnProperty.call solves the problem. but what is the reason?

@sudheer594
Copy link

I dont have idea why the performance like this in node.Hope someone with better knowledge on node innerworkings will clarify .
if you want to know why we have to use Object.prototype.hasOwnProperty.call in favor of hasOwnProperty.Here is a article i found to be useful http://jsperf.com/hasownproperty-call-vs-direct/7
for performance Test
http://jsperf.com/hasownproperty-call-vs-direct/7

@CGavrila
Copy link

CGavrila commented Feb 5, 2015

Can't claim to be an expert on the matter, but hasOwnProperty is defined in V8 and its speed is pretty much determined by what V8 is doing.

I have tried this in v0.11.14 (V8 version 3.26.33 vs 3.14.x in v0.10.x) and it seems that the problem is gone.

Unfortunately, I don't think there's much that can be done about, unless you plan on changing some of the V8 inner workings.

@trevnorris
Copy link

Yes. This is a V8 issue and not much we can do in Node.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants