babel-plugin-loop-optimizer icon indicating copy to clipboard operation
babel-plugin-loop-optimizer copied to clipboard

Preallocate array

Open disovi opened this issue 7 years ago • 9 comments
trafficstars

function timesTwo(arr) {
    var _a = arr;
    var _f = n => n * 2;
    var _r = [];

    for (var _i = 0; _i < _a.length; _i++)
        _r.push(_f(_a[_i], _i, _a));

    return _r;
}

can be optimized:

function timesTwo(arr) {
    var _a = arr;
    var _l = arr.length;
    var _f = n => n * 2;
    var _r = new Array(_l);

    for (var _i = 0; _i < _l; _i++)
        _r[_i] = _f(_a[_i], _i, _a);

    return _r;
}

check my perf: https://jsperf.com/map-performance2/1

disovi avatar Mar 28 '18 15:03 disovi

arrays1 arrays2

kurtextrem avatar Mar 28 '18 15:03 kurtextrem

@kurtextrem as far as I understand, mapped array can't become 'holey' in this case, because you know the size of original array and each element would be filled. And operations becomes slower only if you have holes in the array. Correct me, if I'm wrong.

disovi avatar Mar 28 '18 17:03 disovi

@disovi This is wrong. If you construct an array using new Array(n) where n is greater 0, it becomes holey no matter what. Only [] creates non-holey arrays

kurtextrem avatar Mar 28 '18 19:03 kurtextrem

ok, though @kurtextrem didn't give any links or sources, except that beatufiul image, I've digged it up myself. Here are the results: V8 engine (Chrome/Nodejs) has different kinds of arrays under the hood. In short words - holey (possibly with holes) and packed (optimized). Packed arrays are supposed to have better performance. Preallocated arrays are always holey. Further reading: https://v8project.blogspot.ru/2017/09/elements-kinds-in-v8.html In Firefox there is no such difference: preallocated arrays works as fast as simple arrays.

I've created the jsperf to see the performance distinction: https://jsperf.com/packed-vs-holy-array-preallocated

After multiple runs on Chrome and Firefox from my Windows 10 laptop I can say, that in chrome performance was usually higher on 3% for 'packed' arrays, but sometimes not. In FireFox there was no difference. I've also tried my first jsperf on my laptop and array preallocation gives 20-30% increase of performance on Chrome and Firefox. But sometimes in Firefox native map was faster than the loop!

I'll test it more from desktop tomorrow. But the conclusion for me is to use preallocated and simple loops manualy and in bottlenecks only:)

disovi avatar Mar 28 '18 23:03 disovi

I'm sorry, I was on mobile - but yes, that is the relevant blogpost. Glad that you've learned something.

The benchmark is still micro and synthetic, and doesn't test array access, which probably is the relevant advantage in packed arrays.

kurtextrem avatar Mar 29 '18 07:03 kurtextrem

@kurtextrem the first 4 tests have primarily goal to show the difference between read/write access in holey/packed arrays and packed have increased performance on 3% per second and in Chrome only. If you know about more relevant benchmarks share the link please.

disovi avatar Mar 29 '18 08:03 disovi

@disovi I'm sorry, this was not meant to offend you. You did a great job on that benchmark, it's really extensive. I rather meant, most real-world use cases probably won't write to an array directly after reading an array value in a bigger loop. I could be wrong though, it's just my assumption.

My results (Desktop, i7, latest Chrome Dev) look similar to yours - but packed string vs. holey string is even. I'd personally stick with V8 devs' advice, but it's interesting that there is not a too huge difference.

kurtextrem avatar Mar 29 '18 09:03 kurtextrem

@kurtextrem no problem. I want to believe that one day native map will be faster than both approaches:) Some more results for Ubuntu 16.04.3 LTS, Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz

Map holey (preallocated) faster than packed (push):

  • Chrome 65.0.3325.181: 57%
  • Firefox 59.0.1: 30%

Iteration holey slower than packed:

  • Chrome: 8%
  • Firefox: 0%

disovi avatar Mar 29 '18 16:03 disovi

arrays1 arrays2

it's not true for tools - a tool will never create holley array, so no holley array - no slow operations

budarin avatar Oct 30 '22 21:10 budarin