Skip to content

Commit fb03b86

Browse files
authored
Merge pull request #667 from ignlg/next
Next: Improve performance and bump to v2.7
2 parents c6bce4c + 17cf612 commit fb03b86

File tree

16 files changed

+354
-292
lines changed

16 files changed

+354
-292
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ heap vs array: push + top(50) of 100
4343

4444
## Changelog
4545

46+
### 2.7
47+
48+
- Improves performance of sorting methods. Thanks to @BeatsuDev for the contribution.
49+
- Improves tests and documentation.
50+
4651
### 2.6
4752

4853
- Improves performance of remove and sorting methods.
@@ -69,7 +74,7 @@ heap vs array: push + top(50) of 100
6974
### 2.2
7075

7176
- Fixes `.iterator()` method to follow [Java's PriorityQueue implementation:
72-
](https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html)
77+
](https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html)
7378
> The Iterator provided in method [iterator()](<https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html#iterator()>) is not guaranteed to traverse the elements of the priority queue in any particular order.
7479
7580
Notice that _using the heap directly as an iterator will consume the heap,_ as Python's `heapq` implementation does.

dist/heap-js.es5.js

Lines changed: 72 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ var HeapAsync = /** @class */ (function () {
643643
if (array) {
644644
this.heapArray = __spreadArray$1([], __read$1(array), false);
645645
}
646-
i = Math.floor(this.heapArray.length);
646+
i = Math.floor(this.heapArray.length / 2);
647647
_a.label = 1;
648648
case 1:
649649
if (!(i >= 0)) return [3 /*break*/, 4];
@@ -1023,53 +1023,52 @@ var HeapAsync = /** @class */ (function () {
10231023
* @param {Number} k Another node index
10241024
*/
10251025
HeapAsync.prototype._moveNode = function (j, k) {
1026-
var _a;
1027-
_a = __read$1([this.heapArray[k], this.heapArray[j]], 2), this.heapArray[j] = _a[0], this.heapArray[k] = _a[1];
1026+
var temp = this.heapArray[j];
1027+
this.heapArray[j] = this.heapArray[k];
1028+
this.heapArray[k] = temp;
10281029
};
10291030
/**
10301031
* Move a node down the tree (to the leaves) to find a place where the heap is sorted.
10311032
* @param {Number} i Index of the node
10321033
*/
10331034
HeapAsync.prototype._sortNodeDown = function (i) {
10341035
return __awaiter(this, void 0, void 0, function () {
1035-
var length, left, right, best, _a, _b;
1036-
return __generator$1(this, function (_c) {
1037-
switch (_c.label) {
1036+
var length, originalIndex, value, left, right, best, _a;
1037+
return __generator$1(this, function (_b) {
1038+
switch (_b.label) {
10381039
case 0:
10391040
length = this.heapArray.length;
1040-
_c.label = 1;
1041-
case 1:
1041+
originalIndex = i;
1042+
value = this.heapArray[i];
10421043
left = 2 * i + 1;
1044+
_b.label = 1;
1045+
case 1:
1046+
if (!(left < length)) return [3 /*break*/, 5];
10431047
right = left + 1;
1044-
best = i;
1045-
_a = left < length;
1046-
if (!_a) return [3 /*break*/, 3];
1047-
return [4 /*yield*/, this.compare(this.heapArray[left], this.heapArray[best])];
1048+
_a = right >= length;
1049+
if (_a) return [3 /*break*/, 3];
1050+
return [4 /*yield*/, this.compare(this.heapArray[left], this.heapArray[right])];
10481051
case 2:
1049-
_a = (_c.sent()) < 0;
1050-
_c.label = 3;
1052+
_a = (_b.sent()) < 0;
1053+
_b.label = 3;
10511054
case 3:
1052-
if (_a) {
1053-
best = left;
1054-
}
1055-
_b = right < length;
1056-
if (!_b) return [3 /*break*/, 5];
1057-
return [4 /*yield*/, this.compare(this.heapArray[right], this.heapArray[best])];
1055+
best = _a ? left
1056+
: right;
1057+
return [4 /*yield*/, this.compare(this.heapArray[best], value)];
10581058
case 4:
1059-
_b = (_c.sent()) < 0;
1060-
_c.label = 5;
1061-
case 5:
1062-
if (_b) {
1063-
best = right;
1059+
if ((_b.sent()) < 0) {
1060+
this.heapArray[i] = this.heapArray[best];
1061+
i = best;
1062+
left = 2 * i + 1;
10641063
}
1065-
if (best === i)
1066-
return [3 /*break*/, 7];
1067-
this._moveNode(i, best);
1068-
i = best;
1069-
_c.label = 6;
1070-
case 6:
1064+
else
1065+
return [3 /*break*/, 5];
10711066
return [3 /*break*/, 1];
1072-
case 7: return [2 /*return*/];
1067+
case 5:
1068+
if (i !== originalIndex) {
1069+
this.heapArray[i] = value;
1070+
}
1071+
return [2 /*return*/];
10731072
}
10741073
});
10751074
});
@@ -1080,22 +1079,30 @@ var HeapAsync = /** @class */ (function () {
10801079
*/
10811080
HeapAsync.prototype._sortNodeUp = function (i) {
10821081
return __awaiter(this, void 0, void 0, function () {
1083-
var pi;
1082+
var value, originalIndex, pi;
10841083
return __generator$1(this, function (_a) {
10851084
switch (_a.label) {
10861085
case 0:
1087-
if (!(i > 0)) return [3 /*break*/, 2];
1088-
pi = HeapAsync.getParentIndexOf(i);
1089-
return [4 /*yield*/, this.compare(this.heapArray[i], this.heapArray[pi])];
1086+
value = this.heapArray[i];
1087+
originalIndex = i;
1088+
_a.label = 1;
10901089
case 1:
1090+
if (!(i > 0)) return [3 /*break*/, 3];
1091+
pi = HeapAsync.getParentIndexOf(i);
1092+
return [4 /*yield*/, this.compare(value, this.heapArray[pi])];
1093+
case 2:
10911094
if ((_a.sent()) < 0) {
1092-
this._moveNode(i, pi);
1095+
this.heapArray[i] = this.heapArray[pi];
10931096
i = pi;
10941097
}
10951098
else
1096-
return [3 /*break*/, 2];
1097-
return [3 /*break*/, 0];
1098-
case 2: return [2 /*return*/];
1099+
return [3 /*break*/, 3];
1100+
return [3 /*break*/, 1];
1101+
case 3:
1102+
if (i !== originalIndex) {
1103+
this.heapArray[i] = value;
1104+
}
1105+
return [2 /*return*/];
10991106
}
11001107
});
11011108
});
@@ -1398,8 +1405,7 @@ var Heap = /** @class */ (function () {
13981405
if (idx <= 0) {
13991406
return -1;
14001407
}
1401-
var whichChildren = idx % 2 ? 1 : 2;
1402-
return Math.floor((idx - whichChildren) / 2);
1408+
return (idx - 1) >> 1;
14031409
};
14041410
/**
14051411
* Gets sibling index for given index.
@@ -1741,7 +1747,7 @@ var Heap = /** @class */ (function () {
17411747
if (array) {
17421748
this.heapArray = __spreadArray([], __read(array), false);
17431749
}
1744-
for (var i = Math.floor(this.heapArray.length); i >= 0; --i) {
1750+
for (var i = Heap.getParentIndexOf(this.length - 1); i >= 0; --i) {
17451751
this._sortNodeDown(i);
17461752
}
17471753
this._applyLimit();
@@ -2126,45 +2132,53 @@ var Heap = /** @class */ (function () {
21262132
* @param {Number} k Another node index
21272133
*/
21282134
Heap.prototype._moveNode = function (j, k) {
2129-
var _a;
2130-
_a = __read([this.heapArray[k], this.heapArray[j]], 2), this.heapArray[j] = _a[0], this.heapArray[k] = _a[1];
2135+
var temp = this.heapArray[j];
2136+
this.heapArray[j] = this.heapArray[k];
2137+
this.heapArray[k] = temp;
21312138
};
21322139
/**
21332140
* Move a node down the tree (to the leaves) to find a place where the heap is sorted.
21342141
* @param {Number} i Index of the node
21352142
*/
21362143
Heap.prototype._sortNodeDown = function (i) {
21372144
var length = this.heapArray.length;
2138-
while (true) {
2139-
var left = 2 * i + 1;
2145+
var originalIndex = i;
2146+
var value = this.heapArray[i];
2147+
var left = 2 * i + 1;
2148+
while (left < length) {
21402149
var right = left + 1;
2141-
var best = i;
2142-
if (left < length && this.compare(this.heapArray[left], this.heapArray[best]) < 0) {
2143-
best = left;
2150+
var best = right >= length || this.compare(this.heapArray[left], this.heapArray[right]) < 0 ? left : right;
2151+
if (this.compare(this.heapArray[best], value) < 0) {
2152+
this.heapArray[i] = this.heapArray[best];
2153+
i = best;
2154+
left = 2 * i + 1;
21442155
}
2145-
if (right < length && this.compare(this.heapArray[right], this.heapArray[best]) < 0) {
2146-
best = right;
2147-
}
2148-
if (best === i)
2156+
else
21492157
break;
2150-
this._moveNode(i, best);
2151-
i = best;
2158+
}
2159+
if (i !== originalIndex) {
2160+
this.heapArray[i] = value;
21522161
}
21532162
};
21542163
/**
21552164
* Move a node up the tree (to the root) to find a place where the heap is sorted.
21562165
* @param {Number} i Index of the node
21572166
*/
21582167
Heap.prototype._sortNodeUp = function (i) {
2168+
var value = this.heapArray[i];
2169+
var originalIndex = i;
21592170
while (i > 0) {
21602171
var pi = Heap.getParentIndexOf(i);
2161-
if (this.compare(this.heapArray[i], this.heapArray[pi]) < 0) {
2162-
this._moveNode(i, pi);
2172+
if (this.compare(value, this.heapArray[pi]) < 0) {
2173+
this.heapArray[i] = this.heapArray[pi];
21632174
i = pi;
21642175
}
21652176
else
21662177
break;
21672178
}
2179+
if (i !== originalIndex) {
2180+
this.heapArray[i] = value;
2181+
}
21682182
};
21692183
/**
21702184
* Return the top (highest value) N elements of the heap, without corner cases, unsorted

0 commit comments

Comments
 (0)