Skip to content

Commit 19846b3

Browse files
🚴 perf(DeepIterator): Avoid creating many temporary arrays.
1 parent 076ee35 commit 19846b3

File tree

7 files changed

+94
-29
lines changed

7 files changed

+94
-29
lines changed

src/0-core/_fast/fast-iterators/BackwardIterator.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,21 @@ import DeepIterator, {DOWNWARD} from './DeepIterator.js';
1111
*/
1212
export default function BackwardIterator(tree) {
1313
assert(tree instanceof Deep);
14-
this._stack = tree._right._list();
15-
this._level = this._stack.map(() => 0);
16-
this._tree = tree;
14+
this._stack = [];
15+
this._level = [];
1716
this._direction = DOWNWARD;
1817
this._currentLevel = 0;
19-
this._treeStack = [];
18+
this._treeStack = [tree];
2019
}
2120

2221
BackwardIterator.prototype = new DeepIterator();
2322

24-
BackwardIterator.prototype._downwardStep = function () {
25-
this._stack = this._tree._right._list();
23+
BackwardIterator.prototype._downwardStep = function (tree) {
24+
tree._right._backward(this);
2625
};
2726

2827
BackwardIterator.prototype._upwardStep = function () {
29-
this._stack = this._tree._left._list();
28+
this._treeStack.pop()._left._backward(this);
3029
};
3130

3231
BackwardIterator.prototype._traverse = function (level, x) {

src/0-core/_fast/fast-iterators/DeepIterator.js

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,32 +29,30 @@ DeepIterator.prototype.next = function () {
2929
// eslint-disable-next-line default-case
3030
switch (this._direction) {
3131
case DOWNWARD:
32-
this._tree._middle = this._tree._middle._force();
33-
if (this._tree._middle instanceof Deep) {
34-
this._treeStack.push(this._tree);
35-
this._tree = this._tree._middle;
36-
this._downwardStep();
32+
// eslint-disable-next-line no-case-declarations
33+
const tree = this._treeStack.pop()._force();
34+
if (tree instanceof Deep) {
35+
this._downwardStep(tree);
3736
++this._currentLevel;
38-
this._level = this._stack.map(() => this._currentLevel);
37+
this._treeStack.push(tree, tree._middle);
3938
break;
4039
} else {
40+
assert(this._treeStack.length >= 1);
4141
this._direction = UPWARD;
42-
if (this._tree._middle instanceof Single) {
43-
this._stack = [this._tree._middle.a];
44-
this._level = [this._currentLevel + 1];
42+
if (tree instanceof Single) {
43+
this._stack.push(tree.a);
44+
this._level.push(this._currentLevel);
4545
break;
4646
}
4747

48-
assert(this._tree._middle instanceof Empty);
48+
assert(tree instanceof Empty);
4949
}
5050

5151
case UPWARD:
52-
if (this._currentLevel === -1) return {done: true};
53-
assert(this._tree instanceof Deep);
52+
if (this._currentLevel === 0) return {done: true};
53+
assert(this._treeStack[this._treeStack.length - 1] instanceof Deep);
54+
--this._currentLevel;
5455
this._upwardStep();
55-
this._level = this._stack.map(() => this._currentLevel);
56-
57-
this._tree = --this._currentLevel === -1 ? null : this._treeStack.pop();
5856
}
5957
/* eslint-enable no-fallthrough */
6058
}

src/0-core/_fast/fast-iterators/ForwardIterator.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,21 @@ import DeepIterator, {DOWNWARD} from './DeepIterator.js';
1111
*/
1212
export default function ForwardIterator(tree) {
1313
assert(tree instanceof Deep);
14-
this._stack = tree._left._list().reverse();
15-
this._level = this._stack.map(() => 0);
16-
this._tree = tree;
14+
this._stack = [];
15+
this._level = [];
1716
this._direction = DOWNWARD;
1817
this._currentLevel = 0;
19-
this._treeStack = [];
18+
this._treeStack = [tree];
2019
}
2120

2221
ForwardIterator.prototype = new DeepIterator();
2322

24-
ForwardIterator.prototype._downwardStep = function () {
25-
this._stack = this._tree._left._list().reverse();
23+
ForwardIterator.prototype._downwardStep = function (tree) {
24+
tree._left._forward(this);
2625
};
2726

2827
ForwardIterator.prototype._upwardStep = function () {
29-
this._stack = this._tree._right._list().reverse();
28+
this._treeStack.pop()._right._forward(this);
3029
};
3130

3231
ForwardIterator.prototype._traverse = function (level, x) {

src/1-digit/1-One.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,12 @@ One.prototype._isolated_tail = function (parent) {
231231
parent._right,
232232
);
233233
};
234+
235+
One.prototype._backward =
236+
// eslint-disable-next-line no-multi-assign
237+
One.prototype._forward = function (iterator) {
238+
assert(iterator._stack.length === 0);
239+
assert(iterator._level.length === 0);
240+
iterator._stack.push(this.a);
241+
iterator._level.push(iterator._currentLevel);
242+
};

src/1-digit/2-Two.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,17 @@ Two.prototype._isolated_tail = function (parent) {
233233
assert(parent._left === this);
234234
return new Deep(parent.M, this.tail(), parent._middle, parent._right);
235235
};
236+
237+
Two.prototype._forward = function (iterator) {
238+
assert(iterator._stack.length === 0);
239+
assert(iterator._level.length === 0);
240+
iterator._stack.push(this.b, this.a);
241+
iterator._level.push(iterator._currentLevel, iterator._currentLevel);
242+
};
243+
244+
Two.prototype._backward = function (iterator) {
245+
assert(iterator._stack.length === 0);
246+
assert(iterator._level.length === 0);
247+
iterator._stack.push(this.a, this.b);
248+
iterator._level.push(iterator._currentLevel, iterator._currentLevel);
249+
};

src/1-digit/3-Three.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,25 @@ Three.prototype._isolated_tail = function (parent) {
243243
assert(parent._left === this);
244244
return new Deep(parent.M, this.tail(), parent._middle, parent._right);
245245
};
246+
247+
Three.prototype._forward = function (iterator) {
248+
assert(iterator._stack.length === 0);
249+
assert(iterator._level.length === 0);
250+
iterator._stack.push(this.c, this.b, this.a);
251+
iterator._level.push(
252+
iterator._currentLevel,
253+
iterator._currentLevel,
254+
iterator._currentLevel,
255+
);
256+
};
257+
258+
Three.prototype._backward = function (iterator) {
259+
assert(iterator._stack.length === 0);
260+
assert(iterator._level.length === 0);
261+
iterator._stack.push(this.a, this.b, this.c);
262+
iterator._level.push(
263+
iterator._currentLevel,
264+
iterator._currentLevel,
265+
iterator._currentLevel,
266+
);
267+
};

src/1-digit/4-Four.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,27 @@ Four.prototype._isolated_tail = function (parent) {
284284
assert(parent._left === this);
285285
return new Deep(parent.M, this.tail(), parent._middle, parent._right);
286286
};
287+
288+
Four.prototype._forward = function (iterator) {
289+
assert(iterator._stack.length === 0);
290+
assert(iterator._level.length === 0);
291+
iterator._stack.push(this.d, this.c, this.b, this.a);
292+
iterator._level.push(
293+
iterator._currentLevel,
294+
iterator._currentLevel,
295+
iterator._currentLevel,
296+
iterator._currentLevel,
297+
);
298+
};
299+
300+
Four.prototype._backward = function (iterator) {
301+
assert(iterator._stack.length === 0);
302+
assert(iterator._level.length === 0);
303+
iterator._stack.push(this.a, this.b, this.c, this.d);
304+
iterator._level.push(
305+
iterator._currentLevel,
306+
iterator._currentLevel,
307+
iterator._currentLevel,
308+
iterator._currentLevel,
309+
);
310+
};

0 commit comments

Comments
 (0)