I was testing performance (with chrome timeline) on cases if variable defined inside a closure. So it's values would not be exposed to user.
As expected run_proto_fn
run few times faster and with minimal garbage collections, and low memory heap.
But run_proto_obj
happened to make exact opposite, as if it was costly having non-function values at object prototype property properties.
Can someone share some clarity here?
SOME = function(){};
SOME.prototype.exe = function(v){
var x = {
a:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
b:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
c:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
};
return x[v];
};
SOME2 = function(){};
SOME2.prototype.exe = function(v){
return this.exes[v];
};
SOME2.prototype.exes = {
a:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
b:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
c:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
};
SOME_FN = function(){};
SOME_FN.prototype.exe = function(v){
var x = {
a: function(p){this.p1 = p;return this;},
b:function(p){this.p2 = p*3;return this;},
c:function(p){this.p3 = p*99;return this;},
};
return x[v].call(this,42);
};
SOME_FN2 = function(){};
SOME_FN2.prototype.exe = function(v){
return this.exes[v].call(this,42);
};
SOME_FN2.prototype.exes = {
a: function(p){this.p1 = p;return this;},
b:function(p){this.p2 = p*3;return this;},
c:function(p){this.p3 = p*99;return this;},
};
var a1 = a2 = a_fn1 = a_fn2 = [];
var run_local_obj = function(){
for (var i = 1000000 - 1; i >= 0; i--) {
x1 = new SOME();
x1.exe('a');
a1.push(x1);
}
};
var run_proto_obj = function(){
for (var i = 1000000 - 1; i >= 0; i--) {
x2 = new SOME2();
x2.exe('a');
a2.push(x2);
}
};
var run_local_fn = function(){
for (var i = 1000000 - 1; i >= 0; i--) {
x1 = new SOME_FN();
x1.exe('a');
x1.exe('b');
x1.exe('c');
a_fn1.push(x1);
}
};
var run_proto_fn = function(){
for (var i = 1000000 - 1; i >= 0; i--) {
x2 = new SOME_FN2();
x2.exe('a');
x2.exe('b');
x2.exe('c');
a_fn2.push(x2);
}
};
<button onclick="run_local_obj(this)">local obj</button>
<button onclick="run_proto_obj(this)">proto obj</button>
<button onclick="run_local_fn(this)">local obj FN</button>
<button onclick="run_proto_fn(this)">proto obj</button>
I have heard a phrase:
closure variable is defined each time that function runs
but still, i'ts foggy.
I tried to run the measurements and first what I noticed is that it is hard to understand what is going on just using the code from your question.
If I run these tests one-by-one (clicking at the buttons and looking at the timeline) then for each next run the results differ much.
From few runs it looked like the third (run_local_fn
) is usually longer than others.
Then I tried to run them in the backward order (click buttons from 4 to 1) and got the completely different result - the run_local_obj
was the longest.
So I modified the test code a bit, to be able to get stable results.
Full code is here, you can clone the repo and test it locally.
Here is how I run each test in Chrome (I launched it using python -m SimpleHTTPServer 8082
inside the js-perf-test
folder):
Results are stable and repeatable (both timings and timeline view), here is one of tests:
So what do we see here is:
1) The run_proto_obj
is the fastest and run_local_obj
is close to it.
I think it is expected for run_proto_obj
to be most efficient since it uses statically defined object with strings.
And JS engine is probably able to optimize the run_local_obj
, so the x
object is re-used and not created each time.
2) The run_local_fn
is the slowest.
Here we have the local x
object and dynamic strings calculation, more floating
parts than in other tests.
3) The run_proto_fn
is faster than run_local_fn
, but slower than first two functions.
I think this is also expected, the object with a, b, c
is defined only once (so it is faster than run_local_fn
).
And comparing to the first two functions, it calculates the resulting strings dynamically, so it is slower.
So back to your question:
As expected run_proto_fn run few times faster and with minimal garbage collections, and low memory heap. But run_proto_obj happened to make exact opposite, as if it was costly having non-function values at object prototype property properties.
It looks for me like you just didn't setup the experiment properly.
According to the results above, run_proto_obj
is actually the fastest.
Update: I just tried the same test in Firefox, results are similar:
The run_proto_obj
is the fastest and run_local_fn
is the slowest.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With