Skip to main content
3 of 3
edited title
user64494
  • 29.1k
  • 4
  • 29
  • 56

How to use Compile to optimize the performance of a function calculating the distance between two points?

I want to create a function that finds the real space distance between two three-dimensional points. Each point is a list of three real numbers.

I can create functions dist1, dist2, and distCompiled1 and test them on example points myPoint1 and myPoint2:

dist1[pt1_List, pt2_List] := Sqrt[(pt1[[1]] - pt2[[1]])^2 + (pt1[[2]] - pt2[[2]])^2
   + (pt1[[3]] - pt2[[3]])^2];
dist2[pt1_List, pt2_List] := Sqrt[(pt1 - pt2).(pt1 - pt2)];
distCompiled1 := Compile[{{pt1, _Real, 1}, {pt2, _Real, 1}},
   Sqrt[(pt1 - pt2).(pt1 - pt2)]];

myPoint1 = {1.0, 2.0, 3.0};
myPoint2 = {4.0, 5.0, 6.0};

dist1[myPoint1, myPoint2]
dist2[myPoint1, myPoint2]
distCompiled1[myPoint1, myPoint2]

5.19615

5.19615

5.19615

So, dist1, dist2, and distCompiled1 all give the same result.

But, I will be computing distances between many millions of points, so I want to optimize my function for speed. If I calculate the distance between 1 million pairs of points, for example, I get the following results:

dist1[pt1_List, pt2_List] := Sqrt[(pt1[[1]] - pt2[[1]])^2 + (pt1[[2]] - pt2[[2]])^2
   + (pt1[[3]] - pt2[[3]])^2];
dist2[pt1_List, pt2_List] := Sqrt[(pt1 - pt2).(pt1 - pt2)];
distCompiled1 := Compile[{{pt1, _Real, 1}, {pt2, _Real, 1}},
   Sqrt[(pt1 - pt2).(pt1 - pt2)]];
maxVal = 8.009469032;
numPts = 10^6;
SeedRandom[1234];
coords1 = Table[RandomReal[{0, maxVal}, 3], {numPts}];
SeedRandom[1235];
coords2 = Table[RandomReal[{0, maxVal}, 3], {numPts}];

(* Time the computations, and verify that the functions give the same results. *)
AbsoluteTiming[
dist1Result = Table[dist1[coords1[[i]], coords2[[i]]], {i, 1, numPts}];
]
AbsoluteTiming[
dist2Result = Table[dist2[coords1[[i]], coords2[[i]]], {i, 1, numPts}];
]
AbsoluteTiming[
distCompiled1Result = Table[distCompiled1[coords1[[i]], coords2[[i]]], {i, 1, numPts}];
]
(dist1Result == dist2Result) && (dist2Result == distCompiled1Result)

{6.725385, Null}

{5.900337, Null}

{30.191727, Null}

True

  • Why is distCompiled1, the function that uses Compile, so much slower -- not faster -- than the others that don't use Compile?

  • How can I rewrite distCompiled1 so that it ideally runs faster than dist1 and dist2?

Andrew
  • 10.5k
  • 5
  • 53
  • 106