Reputation: 799
Is there any way to optimize this method of searching?
for (var i=0;i<dots.length;i++) {
var blist = [];
for (var n=0;n<dots.length;n++) {
if (dots[n][1]>(dots[i][1]-90)
&& dots[n][1]<(dots[i][1]+90)
&& dots[n][2]>(dots[i][2]-90)
&& dots[n][2]<(dots[i][2]+90)) {
if (!(n === i)) blist.push(n);
}
}
dots[x][1]
is the x-coordinate and dots[x][2]
is the y-coordinate.
I have 1000 dots, and need to find the dots surrounding each dot, so that results in the
if (dots[n][1]>(dots[i][1]-90)
&& dots[n][1]<(dots[i][1]+90)
&& dots[n][2]>(dots[i][2]-90)
&& dots[n][2]<(dots[i][2]+90))
Running a million times a second, so is there a way to optimize this?
Upvotes: 1
Views: 97
Reputation: 50807
Here's a sketch of a solution. It may be the same idea TravisJ was suggesting, although that's not clear to me. It really is only a sketch, and would take significant code to implement.
If you partition your space into 90 unit x 90 unit sections, then a dot in a particular section can only be close enough to a dot in that section or to a dot in one of that section's eight neighbors. This could significantly reduce the number of pairs you have to compare. The cost, of course is algorithmic complexity:
Math.floor(something / 90)
operations.I have not tested this, except in my head. It should work, but I have not tried to write any code. And the code would not be trivial. I don't think it's weeks of work, but it's not something to whip together in a few minutes either.
I believe it could significantly increase the speed, but that will depend upon how many matches there are, how many dots there are relative to the number of sections.
Upvotes: 0
Reputation: 50807
One way to cut your time in half would be not to double-check each pair:
for (var i = 0, len = dots.length; i < len - 1; i++) {
var blist = [];
for (var n = i + 1; n < len; n++) {
if (dots[n][1]>(dots[i][1]-90)
&& dots[n][1]<(dots[i][1]+90)
&& dots[n][2]>(dots[i][2]-90)
&& dots[n][2]<(dots[i][2]+90)) {
blist.push(i);
blist.push(n);
}
}
}
Note the change in loop boundaries. This allows me to check each pair only once and skip the (n === i)
check.
I also cache dot.length
, probably not a big deal, but worth doing for a tight loop.
Still, that should be an improvement of more than 50%. While that could help, it's not the orders of magnitude change that might be required for this sort of issue.
Upvotes: 0
Reputation: 82297
Perhaps try using a data structure for your dots like this
var Dot = function(){
var x = 0;
var y = 0;
var Up;
var Right;
var Left;
var Down;
function init(xVal,yVal)
{
x = xVal;
y = yVal;
}
function GetUp()
{
return Up;
}
function SetUp(UpDot)
{
Up = UpDot;
}
return
{
init: init,
GetUp: GetUp,
SetUp: SetUp
};
};
and then use it like this
var Dots = [];
var firstDot = new Dot();
Dots.push(firstDot);
var secondDot = new Dot();
secondDot.init(0,90);
secondDot.SetUp(firstDot);
Dots.push(secondDot);
Obviously, more would need to be added and configured to match your situation. However, what this would allow you to do was iterate through dots and then check weather there existed a near dot making the time O(n) instead of O(n^2) and thus saving you 900,000 checks.
Upvotes: 1