performance - Javascript nested function call optimization -
edit! changed answer own after lot of follow-up research showed there isn't simple answer question. see below!
so, in followup last question, i'm trying better handle on best javascript practices optimize performance. following example, i'm testing in chrome 28.0.1500.70 using in-browser profiler.
i've got math functions encapsulated in object getting called few hundred k-times second , trying shave bit of execution time.
i've done optimization making local copies of parent objects locals locals in called functions , got decent (~16%) performance boost. however, when did same calling function parent object, got huge (~100%) performance increase.
the original setup calcneighbors calling fellow parent object function cirind via this.cirind.
making local var copy of cirind , calling instead gave huge performance gain, less half execution time before calcneighbors.
however, making cirind inline function in calcneighbors caused return same slower performance calling parent object.
i'm perplexed this. suppose quirk in chrome's profiler (cirind doesn't show @ in second case) there noticeable performance gain in application when use case 2.
can explain why case 2 faster case 1 more importantly, why case 3 seems not give performance gain?
the functions in question here:
calling parent object:
window.bgvars = { <snip> "cirind": function(index, mod){ //returns modulus, array-wrapping value implement circular array if(index<0){index+=mod;} return index%mod; }, "calcneighbors": function(rep){ var foo = this.xblocks; var grid = this.cgrid; var mod = grid.length; var cirind = this.cirind; var neighbors = grid[this.cirind(rep-foo-1, mod)] + grid[this.cirind(rep-foo, mod)] + grid[this.cirind(rep-foo+1, mod)] + grid[this.cirind(rep-1, mod)] + grid[this.cirind(rep+1, mod)] + grid[this.cirind(rep+foo-1, mod)] + grid[this.cirind(rep+foo, mod)] + grid[this.cirind(rep+foo+1, mod)]; return neighbors; }, <snip> }
calling via local variable:
window.bgvars = { <snip> "cirind": function(index, mod){ //returns modulus, array-wrapping value implement circular array if(index<0){index+=mod;} return index%mod; }, "calcneighbors": function(rep){ var foo = this.xblocks; var grid = this.cgrid; var mod = grid.length; var cirind = this.cirind; var neighbors = grid[cirind(rep-foo-1, mod)] + grid[cirind(rep-foo, mod)] + grid[cirind(rep-foo+1, mod)] + grid[cirind(rep-1, mod)] + grid[cirind(rep+1, mod)] + grid[cirind(rep+foo-1, mod)] + grid[cirind(rep+foo, mod)] + grid[cirind(rep+foo+1, mod)]; return neighbors; }, <snip> }
calling inline:
window.bgvars = { <snip> "calcneighbors": function(rep){ var foo = this.xblocks; var grid = this.cgrid; var mod = grid.length; function cirind(index, mod){ //returns modulus, array-wrapping value implement circular array if(index<0){index+=mod;} return index%mod; } var neighbors = grid[cirind(rep-foo-1, mod)] + grid[cirind(rep-foo, mod)] + grid[cirind(rep-foo+1, mod)] + grid[cirind(rep-1, mod)] + grid[cirind(rep+1, mod)] + grid[cirind(rep+foo-1, mod)] + grid[cirind(rep+foo, mod)] + grid[cirind(rep+foo+1, mod)]; return neighbors; }, <snip> }
the reason there relatively time involved in number 1 should obvious. access entire object scope, , have find property.
number 2 , 3 both pointers function, there no seeking.
a resource testing these types of situations jsperf, , highly recommend recreating scenario there , running test see exact differences , whether or not significant you.
Comments
Post a Comment