3 ms·
I am scratching my head at how someone can write a blog post correcting code and leaving such egregious code as a revision. The last snippet of code is still bu
by goldenkey 13y ago
I am scratching my head at how someone can write a blog post correcting code and leaving such egregious code as a revision. The last snippet of code is still busted and very cringeworthy
The proper way to do alternate behavior for the first iteration, would be this...
It's O(n) versus the authors O(2n)
if(attributeArray instanceof Array) {
if (attributeArray.length >= 1){
// do something with attributeArray[0]
for (var i = 1; i < attributeArray.length; ++i)
// do something different with attributeArray[index]
}
}
- inglor 13y agoNot to mention the anti pattern of doing this in the first place. When manipulating collections - you almost always want .map .filter .reduce .some .all or a variation of thereof and not a plain old for loop for this sort of thing, doing this a million or a billion times a second theoretically shouldn't matter. (explained in : http://stackoverflow.com/a/17253577/1348195 http://stackoverflow.com/a/17253577/1348195) Also, checking for instanceof Array is a JS anti pattern to begin with and makes code a lot less generic.
- goldenkey 13y agoI agree that the Array methods are extremely useful other than their ugly performance-sacrificing function scope. In this case though, when you need alternate behavior for the first index, it is much clearer to read a standard for loop with some precursor code behind it, than to read a forEach loop with an if-else.
- inglor 13y agoReally? You find the above loop more readable than: if(array.length > 0) doFunction(array[0]); array.slice(1).forEach(doOtherFunction);
- goldenkey 13y agoYou're kind of cheating because you're using slice which will create a copy of the Array, and that's not cheap if the array is large.
- inglor 13y agoPeople use arrays for things like queues and stacks all the time in JavaScript - they're _much_ slower than hand rolled collection (eg. http://jsperf.com/deque-vs-array-2 http://jsperf.com/deque-vs-array-2 ) - why not micro optimize that as well? If you have a very large array of course optimization can/should be considered but that's simply not the average case.
- goldenkey 13y agoI actually like the slice code for it's ease of readability. Functional methods are extremely nice and I hope they get faster and faster with the optimization of JS JITs. I never heard of Dequeue [1], that is mighty cool. I agree that premature optimization is not good - but when it can be done cleanly without hurt to the readability of the code, I'd say to keep it in ones' repertoire, to effectively write more performant code, more often, on average. [1] http://code.stephenmorley.org/javascript/queues/ http://code.stephenmorley.org/javascript/queues/
- kzahel 13y agoI prefer for loops because they have easier to read and debug exception stack traces. And typing for(i=;...) is calming for me.
- magicalist 13y agoI see your point, but it's a bit of a stretch to call a style preference an anti-pattern. You even caveat it yourself in your stackoverflow response: "it's also a lot more readable (at least to me)". Agreed on the hideousness of that 'instanceof Array' check.
- robryk 13y agoCan you elaborate on what's wrong with the final solution from the article? I don't see anything wrong there and I wouldn't expect your snippet to be faster.
- goldenkey 13y agoChecking the index in every iteration of a loop will effectively double the amount of operations performed in every iteration of the loop for this scenario. That is, O(2n) versus O(n)
- inglor 13y agoNot really, things like branch prediction and JIT optimizations will kick in pretty fast. This is why these benchmarks on jsperf suck - the code gets a different 'fresh' version every time and jits (like crankshaft in v8 ) don't get to work. Effectively, you're checking 'the performance of interperted JavaScript' most the the time.
- goldenkey 13y agoI bet my bottom dollar that branch prediction is not going to magic away that index dependent if statement in a language like JS, even with Crankshaft in full effect.
- inglor 13y agoHere, it's within 20% of the performance. Definitely not n vs 2n http://jsperf.com/oh-look-branches http://jsperf.com/oh-look-branches
- mraleph 13y agoThe actual percentage depends on the CPU. On mobile the cost would likely be higher (e.g. on my phone it's around 33%), on old CPU can be even higher, but people don't usually care about them these days.
- huherto 13y agoO(n) and O(2n) are equivalent. So run speed is not good argument. IMHO
- goldenkey 13y agoScientifically sure, practically though, it matters when working on large data sets and you're already exhausting the snappiness that you would have liked.
- rdmckenzie 13y agoCorrect, however if this "exact runtime bound" is what you are going for, then please use the correct notation. T(N) = 2N would be legitimate, as would \Theta(N) = 2N. Saying that O(F(N)) = 2N is misleading because the definition of the big-o notation explicitly discards all constant factors and constant annends.
- goldenkey 13y agoThanks, I will use Theta(N) next time. There are a bunch of complexity notations, omega, theta, o, etc. I need to brush up on them [1] [1] http://www.youtube.com/watch?v=6Ol2JbwoJp0 http://www.youtube.com/watch?v=6Ol2JbwoJp0
- magicalist 13y agoIt's still worth noting, as others have, that there's a huge assumption baked in to your estimate: that all operations are created equal when it comes to execution time. If we're going to talk "practically" here :) things like branch prediction will ensure that nothing like 2x the execution time will be spent on just the double conditional. Meanwhile, what you do inside that loop becomes much more important to the time estimate than the conditional (.length is a fast single property lookup, whereas just accessing a value in the array (which is presumably the purpose of this method) will often trigger a bounds check on length, then an offset into a looked-up offset into memory, etc). So it's not really worth doing for speed. All that said, I think yours reads better anyway.