Skip to content

Commit

Permalink
Merge pull request #13154 from webpack/perf/iterable
Browse files Browse the repository at this point in the history
cheaper getIterator
  • Loading branch information
sokra committed Apr 19, 2021
2 parents 4c55729 + c7b1471 commit 28d9589
Showing 1 changed file with 87 additions and 57 deletions.
144 changes: 87 additions & 57 deletions lib/FileSystemInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,92 @@ const DONE_ITERATOR_RESULT = new Set().keys().next();
// Tsh = Timestamp + Hash
// Tshs = Timestamp + Hash combinations

class SnapshotIterator {
constructor(next) {
this.next = next;
}
}

class SnapshotIterable {
constructor(snapshot, getMaps) {
this.snapshot = snapshot;
this.getMaps = getMaps;
}

[Symbol.iterator]() {
let state = 0;
/** @type {IterableIterator<string>} */
let it;
/** @type {(Snapshot) => (Map<string, any> | Set<string>)[]} */
let getMaps;
/** @type {(Map<string, any> | Set<string>)[]} */
let maps;
/** @type {Snapshot} */
let snapshot;
let queue;
return new SnapshotIterator(() => {
for (;;) {
switch (state) {
case 0:
snapshot = this.snapshot;
getMaps = this.getMaps;
maps = getMaps(snapshot);
state = 1;
/* falls through */
case 1:
if (maps.length > 0) {
const map = maps.pop();
if (map !== undefined) {
it = map.keys();
state = 2;
} else {
break;
}
} else {
state = 3;
break;
}
/* falls through */
case 2: {
const result = it.next();
if (!result.done) return result;
state = 1;
break;
}
case 3: {
const children = snapshot.children;
if (children !== undefined) {
if (children.size === 1) {
// shortcut for a single child
// avoids allocation of queue
for (const child of children) snapshot = child;
maps = getMaps(snapshot);
state = 1;
break;
}
if (queue === undefined) queue = [];
for (const child of children) {
queue.push(child);
}
}
if (queue !== undefined && queue.length > 0) {
snapshot = queue.pop();
maps = getMaps(snapshot);
state = 1;
break;
} else {
state = 4;
}
}
/* falls through */
case 4:
return DONE_ITERATOR_RESULT;
}
}
});
}
}

class Snapshot {
constructor() {
this._flags = 0;
Expand Down Expand Up @@ -283,63 +369,7 @@ class Snapshot {
* @returns {Iterable<string>} iterable
*/
_createIterable(getMaps) {
let snapshot = this;
return {
[Symbol.iterator]() {
let state = 0;
/** @type {IterableIterator<string>} */
let it;
let maps = getMaps(snapshot);
const queue = [];
return {
next() {
for (;;) {
switch (state) {
case 0:
if (maps.length > 0) {
const map = maps.pop();
if (map !== undefined) {
it = map.keys();
state = 1;
} else {
break;
}
} else {
state = 2;
break;
}
/* falls through */
case 1: {
const result = it.next();
if (!result.done) return result;
state = 0;
break;
}
case 2: {
const children = snapshot.children;
if (children !== undefined) {
for (const child of children) {
queue.push(child);
}
}
if (queue.length > 0) {
snapshot = queue.pop();
maps = getMaps(snapshot);
state = 0;
break;
} else {
state = 3;
}
}
/* falls through */
case 3:
return DONE_ITERATOR_RESULT;
}
}
}
};
}
};
return new SnapshotIterable(this, getMaps);
}

/**
Expand Down

0 comments on commit 28d9589

Please sign in to comment.