Skip to content

Commit 601e07c

Browse files
committed
Improve traverseArray from quadratic to linear
We use a list as an intermediate representation while building up the result, which has the benefit of O(1) cons, rather than O(n). Then, we just need to convert this list to an array in the final step, which is also O(n). So the complexity of traverse is reduced to O(n) from O(n^2).
1 parent 39f3cf1 commit 601e07c

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

src/Data/Traversable.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,30 @@ exports.traverseArrayImpl = function () {
88
this.fn = fn;
99
}
1010

11-
function consArray(x) {
11+
var emptyList = {};
12+
13+
function consList (x) {
1214
return function (xs) {
13-
return [x].concat(xs);
15+
return { head: x, tail: xs };
1416
};
1517
}
1618

19+
function listToArray (list) {
20+
var arr = [];
21+
while (list !== emptyList) {
22+
arr.push(list.head);
23+
list = list.tail;
24+
}
25+
return arr;
26+
}
27+
1728
return function (apply) {
1829
return function (map) {
1930
return function (pure) {
2031
return function (f) {
2132
/* jshint maxparams: 2 */
2233
var buildFrom = function (x, ys) {
23-
return apply(map(consArray)(f(x)))(ys);
34+
return apply(map(consList)(f(x)))(ys);
2435
};
2536

2637
/* jshint maxparams: 3 */
@@ -36,12 +47,12 @@ exports.traverseArrayImpl = function () {
3647
};
3748

3849
return function (array) {
39-
var result = go(pure([]), array.length, array);
50+
var result = go(pure(emptyList), array.length, array);
4051
while (result instanceof Cont) {
4152
result = result.fn();
4253
}
4354

44-
return result;
55+
return map(listToArray)(result);
4556
};
4657
};
4758
};

0 commit comments

Comments
 (0)