Javascript profiling mystery - closure variables -
i testing performance (with chrome timeline) on cases if variable defined inside closure. it's values not exposed user.
as expected run_proto_fn
run few times faster , minimal garbage collections, , low memory heap.
but run_proto_obj
happened make exact opposite, if costly having non-function values @ object prototype property properties.
can share 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 @ 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 = 1000000 - 1; >= 0; i--) { x1 = new some(); x1.exe('a'); a1.push(x1); } }; var run_proto_obj = function(){ for (var = 1000000 - 1; >= 0; i--) { x2 = new some2(); x2.exe('a'); a2.push(x2); } }; var run_local_fn = function(){ for (var = 1000000 - 1; >= 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 = 1000000 - 1; >= 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 phrase:
closure variable defined each time function runs
but still, i'ts foggy.
i tried run measurements , first noticed is hard understand going on using code question.
if run these tests one-by-one (clicking @ buttons , looking @ timeline) each next run results differ much. few runs looked third (run_local_fn
) longer others.
then tried run them in backward order (click buttons 4 1) , got different result - run_local_obj
longest.
so modified test code bit, able stable results.
full code is here, can clone repo , test locally.
here how run each test in chrome (i launched using python -m simplehttpserver 8082
inside js-perf-test
folder):
- open tab http://localhost:8082/perf.html, open dev tools
- start timeline recording
- click button
- wait results in console (min/max/mean)
- stop timeline recording
results stable , repeatable (both timings , timeline view), here 1 of tests:
- `run_local_obj' - 508.45ms, timeline
- `run_proto_obj' - 433.11ms, timeline
- `run_local_fn' - 756.26ms, timeline
- `run_proto_fn' - 560.62ms, timeline
so see here is:
1) run_proto_obj
fastest , run_local_obj
close it.
i think expected run_proto_obj
efficient since uses statically defined object strings. , js engine able optimize run_local_obj
, x
object re-used , not created each time.
2) run_local_fn
slowest.
here have local x
object , dynamic strings calculation, more floating
parts in other tests.
3) run_proto_fn
faster run_local_fn
, slower first 2 functions.
i think expected, object a, b, c
defined once (so faster run_local_fn
).
and comparing first 2 functions, calculates resulting strings dynamically, slower.
so question:
as expected run_proto_fn run few times faster , minimal garbage collections, , low memory heap. run_proto_obj happened make exact opposite, if costly having non-function values @ object prototype property properties.
it looks me didn't setup experiment properly. according results above, run_proto_obj
fastest.
update: tried same test in firefox, results similar:
- `run_local_obj' - 344.85ms
- `run_proto_obj' - 151.47ms
- `run_local_fn' - 788.08ms
- `run_proto_fn' - 265.21ms
the run_proto_obj
fastest , run_local_fn
slowest.
Comments
Post a Comment