4 ms·
I once optimised a SPA app that had to be really fast for usability reasons (industrial use), I replaced all the 'high level' JS patterns such as map, filter, a
by fvdessen 4y ago
I once optimised a SPA app that had to be really fast for usability reasons (industrial use), I replaced all the 'high level' JS patterns such as map, filter, and frontend framework things to use just if else and for loops and native dom manipulation, and it ended up more than 10x faster, each click would update the app in one frame, it was very noticeable. So yes CPU cycles do matter for websites, even with modern hardware. However the code was more verbose and needed a lot more technical know-how to understand and maintain.
- Veliladon 4y agoYep. In Rust land for instance it'd get compiled down to a for loop and be ridiculously fast. Every time you do a .map or a .filter in JS though it gets abstracted down to a function that makes an allocation for the ENTIRE ARRAY and then copies the entire array into that new array doing whatever you asked to data. The JS VM might be able to optimize some of it away but the abstraction is awful. So if you were to manually run a for loop over an array instead of iterating through it I'm not surprised you got an order of magnitude faster performance.
- gardenhedge 4y agoI'd be interested in a blog post on this. Why is JS map so much slower than a for loop?
- Veliladon 4y agoSo normally when you do a bunch of patterns of .filter(), and/or .map(), and/or .reduce() on an array in most other languages the compiler will normally iterate through the elements doing whatever you requested at each element. No allocations, one quick trip through the entire working set, cache locality works no matter how big the set is. In JavaScript on the other hand it handles the abstraction by constructing a separate function for each pattern you use. In those functions it allocates an array the same size as the working set, iterates through each element, then returns the new array. If you're doing multiple operations at once this means that you have to have multiple allocations and multiple iterations through the entire working set. Because it's doing an allocations it's basically doing an extra memcpy for each additional pattern past one which is a giant slowdown. Then if the working set is too big for the L2 cache it needs to be reloaded from L3 each loop. If the working set is too big for L3 then it needs to reload from main memory EACH TIME. If you wanted to implement patterns as slow as molasses I can think of no better way than to sugar it out like JavaScript did.
- david2ndaccount 4y agoApproximately, the slowest thing you can do in a program is memory allocation (and garbage collection is even slower). JS map allocates an entire new array.
- jimbokun 4y agoInteresting that the speed up you saw was very similar to what the author got from the same kind of changes in C++.