underscore icon indicating copy to clipboard operation
underscore copied to clipboard

Optimize "uniq" to be O(n) instead of O(n^2)

Open Tzook opened this issue 8 years ago • 6 comments

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

Tzook avatar May 13 '16 21:05 Tzook

Coverage Status

Coverage increased (+0.02%) to 96.887% when pulling e4620428175837f4471bde6d370764eb8a2743de on Tzook:master into 53086b0f9f6cb4e2fb4eede82b4ef9f74bca030a on jashkenas:master.

coveralls avatar May 13 '16 22:05 coveralls

Keep in mind this toggles the matching behavior from strict equality to same value zero depending on environment support.

jdalton avatar May 13 '16 23:05 jdalton

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.

Tzook avatar May 14 '16 07:05 Tzook

Yep.

jdalton avatar May 14 '16 07:05 jdalton

Hello everyone, is this PR ever going to be merged, or does it need additional work?

Thanks

forty avatar May 04 '17 08:05 forty

  • 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 the supportsMap out of the function and switch over its value only once instead of repeatedly in every loop iteration.

jgonggrijp avatar May 09 '20 00:05 jgonggrijp