Skip to content

Instantly share code, notes, and snippets.

@redblobgames
Last active October 21, 2022 23:58
Show Gist options
  • Save redblobgames/061edb0d8d8c63f4f56b3dc0b8affc7a to your computer and use it in GitHub Desktop.
Save redblobgames/061edb0d8d8c63f4f56b3dc0b8affc7a to your computer and use it in GitHub Desktop.
C# distance test, are Abs, Pow, or Sqrt slow? Yes - Pow(v,2) is much slower than v*v
using System;
using System.Numerics;
static bool InDistance1(Vector2 pos1, Vector2 pos2, float maxDistance) {
var distance = Math.Sqrt(Math.Pow(Math.Abs(pos2.X - pos1.X), 2) + Math.Pow(Math.Abs(pos2.Y - pos1.Y), 2));
return distance <= maxDistance;
}
static bool InDistance2(Vector2 pos1, Vector2 pos2, float maxDistance) {
var distanceSquared = (pos2.X - pos1.X) * (pos2.X - pos1.X) + (pos2.Y - pos1.Y) * (pos2.Y - pos1.Y);
return distanceSquared <= maxDistance * maxDistance;
}
static bool InDistance3(Vector2 pos1, Vector2 pos2, float maxDistance) {
var distance = Math.Sqrt((pos2.X - pos1.X) * (pos2.X - pos1.X) + (pos2.Y - pos1.Y) * (pos2.Y - pos1.Y));
return distance <= maxDistance;
}
var N = 1000;
var rand = new Random();
var elements = new List<Vector2>();
for (var i = 0; i < N; i++) {
elements.Add(new Vector2((rand.NextInt64() % 1000) - 500,
(rand.NextInt64() % 1000) - 500));
}
for (var run = 0; run < 4; run++) {
var TRIES = 100000;
var count = 0;
var watch = new System.Diagnostics.Stopwatch();
watch.Reset();
watch.Start();
count = 0;
for (var i = 0; i < TRIES; i++) {
foreach (var v in elements) {
if (InDistance1(v, elements[0], 100)) count++;
}
}
watch.Stop();
Console.WriteLine($"using Sqrt, Abs: {watch.ElapsedMilliseconds}ms");
watch.Reset();
watch.Start();
count = 0;
for (var i = 0; i < TRIES; i++) {
foreach (var v in elements) {
if (InDistance2(v, elements[0], 100)) count++;
}
}
watch.Stop();
Console.WriteLine($"using squared distance: {watch.ElapsedMilliseconds}ms");
watch.Reset();
watch.Start();
count = 0;
for (var i = 0; i < TRIES; i++) {
foreach (var v in elements) {
if (InDistance3(v, elements[0], 100)) count++;
}
}
watch.Stop();
Console.WriteLine($"using Sqrt, no Abs: {watch.ElapsedMilliseconds}ms");
}
@redblobgames
Copy link
Author

redblobgames commented Oct 21, 2022

I wanted to compare some distance comparison functions to see how much slower Sqrt would be, but it looks like Pow(v, 2) is much slower than v*v, and Abs and Sqrt are only slight slowdowns.

# dotnet run -c Release
using Sqrt, Abs: 2035ms
using squared distance: 187ms
using Sqrt, no Abs: 212ms
using Sqrt, Abs: 2036ms
using squared distance: 189ms
using Sqrt, no Abs: 212ms
using Sqrt, Abs: 2031ms
using squared distance: 187ms
using Sqrt, no Abs: 212ms
using Sqrt, Abs: 2037ms
using squared distance: 187ms
using Sqrt, no Abs: 213ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment