-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactors ArrayIterator to use an internal index instead of Array#shift() #47
Refactors ArrayIterator to use an internal index instead of Array#shift() #47
Conversation
Hah, great! It does make sense, but we need to clear our buffers every once in a while, right? Now memory will start being flooded pretty soon. |
I am afraid I don't follow. Or maybe I do, not sure. Isn't the array already in memory as it is passed to |
Right, for
It all depends what the software is doing. If the iterator is short-lived, then yes; but it could be longer lived and could then occupy more than it needs. Could we maybe quickly have a look at how it impacts performance to, let's say, truncate the array every 64 elements or so? So whenever |
Ah, good idea! Will tinker and report back. |
^ That same approach could work for |
A good tradeoff seems to |
Setting the splicing threshold to 256 brings the time closer to 3x rather than 10x the non-splicing version. Perhaps making this configurable via an appropriate constructor parameter would be a good idea? EDIT: that was fairly easy, so I went ahead and did it. |
Great stuff, will have a closer look and merge. Thanks a bunch! |
@jacoscaz - IMO it would be useful to still have the option on the I think this would be useful, for instance, in some parts of the Comunica Reasoning components; where I am passing around some rules but need to work with them as arrays in some components. |
@jeswr passing |
@jeswr done! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't too sure about passing a setting to ArrayIterator
that affected only its internals, so I have instead added the preserve
setting. This now brings the following options:
new ArrayIterator(array); // Does not modify array, does not truncate
new ArrayIterator(array, { preserve: false }); // Directly modifies array by truncating every 64 items
new ArrayIterator([...array], { preserve: false }); // Does not modify array, truncates every 64 items
so we can gain additional efficiency by not having to copy the source array.
Niiiiice! Thank you for merging! |
Thanks! This PR is now part of v3.4.0. |
As measured on Node 16.x running on a 13'' 2020 MacBook Pro (Apple Silicon, M1, 16 GB RAM), it takes ~3000ms for the current implementation of ArrayIterator to run through a 200k items array.
Research for #38 and #44 pointed at
Array#shift()
being a potential bottleneck, thus this refactored version that uses an internal index instead of modifying the array. With this version, the same test terminates in ~8ms. The difference is so big to be almost unbelievable but I've managed to reproduce it multiple times. The following should suffice: