underscore
underscore copied to clipboard
Optimize "uniq" to be O(n) instead of O(n^2)
The uniq function does heavy operations that could cause performance issues on big arrays. This commit utilizes the Map object if supported (95% browser support according to caniuse), to make such cases much faster. Running a simple example in Chrome on an array with 10,000 unique elements:
- Before - takes about 8 seconds
- After - takes about 0.03 seconds
Coverage increased (+0.02%) to 96.887% when pulling e4620428175837f4471bde6d370764eb8a2743de on Tzook:master into 53086b0f9f6cb4e2fb4eede82b4ef9f74bca030a on jashkenas:master.
Keep in mind this toggles the matching behavior from strict equality to same value zero depending on environment support.
Good point @jdalton. The only differences according to this table are that -0 is not equal to +0, and that NaN equals to NaN. In my opinion it makes even more sense for the function to use same-value-zero comparison. Having an array with multiple NaNs should result in only one NaN after using unique.
Yep.
Hello everyone, is this PR ever going to be merged, or does it need additional work?
Thanks
- It would have to consistently use SameValueZero, even in environments that don't have
Map
. - There would have to be a new major release of Underscore in which we actually decided to use SameValueZero instead of strict equality everywhere. See #2453. It is not yet decided whether we will ever do that.
- It shouldn't do
if
/else
all over the place. Move thesupportsMap
out of the function and switch over its value only once instead of repeatedly in every loop iteration.