Skip to content

Commit 7ea221e

Browse files
authored
Merge pull request #130 from silvermine/jthomerson/uniq-perf
2 parents 16742bc + 7067397 commit 7ea221e

2 files changed

Lines changed: 47 additions & 8 deletions

File tree

src/utils/uniq.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
const iterateeUniq = <T, U>(arr: T[], iteratee: (value: T, i: number, arr: T[]) => U): T[] => {
22
const result: T[] = [],
3-
seen: U[] = [];
3+
seen = new Set<U>();
44

55
for (let i = 0, length = arr.length; i < length; i++) {
66
const value = arr[i],
77
computed = iteratee(value, i, arr);
88

9-
if (seen.indexOf(computed) === -1) {
10-
seen.push(computed);
9+
if (!seen.has(computed)) {
10+
seen.add(computed);
1111
result.push(value);
1212
}
1313
}
@@ -33,11 +33,7 @@ const sortedUniq = <T, U>(arr: T[]): T[] => {
3333

3434

3535
const standardUniq = <T>(arr: T[]): T[] => {
36-
const result = arr.filter((value, index, _arr) => {
37-
return _arr.indexOf(value) === index;
38-
});
39-
40-
return result;
36+
return Array.from(new Set(arr));
4137
};
4238

4339

tests/utils/uniq.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,47 @@ describe('uniq', () => {
2121
expect(uniq([ 4, 4, 1, 1, 2, 3, 4 ], false, isEven)).to.eql([ 4, 1 ]);
2222
});
2323

24+
25+
it('handles 40,000 elements in under 50ms', () => {
26+
const arr: string[] = [];
27+
28+
for (let i = 0; i < 40000; i++) {
29+
arr.push('item-' + (Math.random() < 0.3 ? i % Math.floor(40000 * 0.7) : i));
30+
}
31+
32+
// Warmup to avoid JIT noise
33+
uniq(arr);
34+
35+
const start = performance.now(),
36+
result = uniq(arr);
37+
38+
expect(performance.now() - start).to.be.lessThan(50);
39+
expect(result.length).to.be.greaterThan(0);
40+
expect(result.length).to.be.lessThan(arr.length);
41+
});
42+
43+
44+
it('handles 40,000 elements with iteratee in under 50ms', () => {
45+
const arr: string[] = [];
46+
47+
for (let i = 0; i < 40000; i++) {
48+
arr.push('item-' + i);
49+
}
50+
51+
// Iteratee that produces many unique computed values, causing the
52+
// seen array to grow large and indexOf to become O(n)
53+
const iteratee = (v: string): string => {
54+
return v + '-computed';
55+
};
56+
57+
// Warmup
58+
uniq(arr, false, iteratee);
59+
60+
const start = performance.now(),
61+
result = uniq(arr, false, iteratee);
62+
63+
expect(performance.now() - start).to.be.lessThan(50);
64+
expect(result.length).to.strictlyEqual(40000);
65+
});
66+
2467
});

0 commit comments

Comments
 (0)