Skip to content

cached this.content and this.socreFunction ( faster 7.5%), and have s… #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 45 additions & 34 deletions astar.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,34 +283,37 @@ function BinaryHeap(scoreFunction) {

BinaryHeap.prototype = {
push: function(element) {
var content = this.content;
// Add the new element to the end of the array.
this.content.push(element);
content.push(element);

// Allow it to sink down.
this.sinkDown(this.content.length - 1);
this.sinkDown(content.length - 1);
},
pop: function() {
var content = this.content;
// Store the first element so we can return it later.
var result = this.content[0];
var result = content[0];
// Get the element at the end of the array.
var end = this.content.pop();
var end = content.pop();
// If there are any elements left, put the end element at the
// start, and let it bubble up.
if (this.content.length > 0) {
this.content[0] = end;
if (content.length !== 0 ) {
content[0] = end;
this.bubbleUp(0);
}
return result;
},
remove: function(node) {
var i = this.content.indexOf(node);
var content = this.content;
var i = content.indexOf(node);

// When it is found, the process seen in 'pop' is repeated
// to fill up the hole.
var end = this.content.pop();
var end = content.pop();

if (i !== this.content.length - 1) {
this.content[i] = end;
if (i !== content.length - 1) {
content[i] = end;

if (this.scoreFunction(end) < this.scoreFunction(node)) {
this.sinkDown(i);
Expand All @@ -326,19 +329,22 @@ BinaryHeap.prototype = {
this.sinkDown(this.content.indexOf(node));
},
sinkDown: function(n) {
var content = this.content;
var scoreFunction = this.scoreFunction;
// Fetch the element that has to be sunk.
var element = this.content[n];

var element = content[n];
//
var elemScore = scoreFunction(element);
var parentN = 0, parent = 0;
// When at 0, an element can not sink any further.
while (n > 0) {

// Compute the parent element's index, and fetch it.
var parentN = ((n + 1) >> 1) - 1;
var parent = this.content[parentN];
parentN = ((n + 1) >> 1) - 1;
parent = content[parentN];
// Swap the elements if the parent is greater.
if (this.scoreFunction(element) < this.scoreFunction(parent)) {
this.content[parentN] = element;
this.content[n] = parent;
if (elemScore < scoreFunction(parent)) {
content[parentN] = element;
content[n] = parent;
// Update 'n' to continue at the new position.
n = parentN;
}
Expand All @@ -349,23 +355,29 @@ BinaryHeap.prototype = {
}
},
bubbleUp: function(n) {
var content = this.content;
var scoreFunction = this.scoreFunction;
// Look up the target element and its score.
var length = this.content.length;
var element = this.content[n];
var elemScore = this.scoreFunction(element);
var length = content.length;
var element = content[n];
var elemScore = scoreFunction(element);
// early declarations with type hints
var child2N = 0, child1N = 0;
var child1Score=0;
var swap = -1 ; // no type change !! -1 stands for no swap. X2 speed increase !!!
var child1=null, child2 = null;

while (true) {
// Compute the indices of the child elements.
var child2N = (n + 1) << 1;
var child1N = child2N - 1;
child2N = (n + 1) << 1;
child1N = child2N - 1;
// This is used to store the new position of the element, if any.
var swap = null;
var child1Score;
swap = -1 ;
// If the first child exists (is inside the array)...
if (child1N < length) {
// Look it up and compute its score.
var child1 = this.content[child1N];
child1Score = this.scoreFunction(child1);
child1 = content[child1N];
child1Score = scoreFunction(child1);

// If the score is less than our element's, we need to swap.
if (child1Score < elemScore) {
Expand All @@ -375,17 +387,16 @@ BinaryHeap.prototype = {

// Do the same checks for the other child.
if (child2N < length) {
var child2 = this.content[child2N];
var child2Score = this.scoreFunction(child2);
if (child2Score < (swap === null ? elemScore : child1Score)) {
child2 = content[child2N];
if ( scoreFunction(child2) < (swap < 0 ? elemScore : child1Score)) {
swap = child2N;
}
}

// If the element needs to be moved, swap it, and continue.
if (swap !== null) {
this.content[n] = this.content[swap];
this.content[swap] = element;
if (swap >= 0 ) {
content[n] = content[swap];
content[swap] = element;
n = swap;
}
// Otherwise, we are done.
Expand All @@ -401,4 +412,4 @@ return {
Graph: Graph
};

});
});