Skip to content

Instantly share code, notes, and snippets.

@mrkybe
Last active October 31, 2022 05:30
Show Gist options
  • Save mrkybe/b8df7d0a40bc387d514f467afeb4307e to your computer and use it in GitHub Desktop.
Save mrkybe/b8df7d0a40bc387d514f467afeb4307e to your computer and use it in GitHub Desktop.
Benchmark Sqrt vs SqrMagnitude in Unity
/*
Results on a Ryzen 3800X, ymmv on mobile, but for desktop,
please just write legible code that conveys your intention.
Modern CPUs are fast.
All results are in milliseconds for 10,000,000 iterations.
In Editor:
Vector3.Distance: 437
(v1-v2).Magnitude: 567
sqrMagnitude.Distance: 432
V3.Magnitude: 592
Normal Build:
Vector3.Distance: 116
(v1-v2).Magnitude: 161
sqrMagnitude.Distance: 129
V3.Magnitude: 169
IL2CPP Build:
Vector3.Distance: 76
(v1-v2).Magnitude: 107
sqrMagnitude.Distance: 59
V3.Magnitude: 59
*/
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using UnityEngine;
using Random = UnityEngine.Random;
public class BenchmarkSqrt : MonoBehaviour
{
int num = 10000000;
void Update()
{
int inRadius1 = 0;
int inRadius2 = 0;
int inRadius3 = 0;
int inRadius4 = 0;
Vector3[] targetPositions = new Vector3[num];
Vector3[] transformPositions = new Vector3[num];
float[] attackRadiuses = new float[num];
for (int i = 0; i < num; i++)
{
targetPositions[i] = Random.insideUnitSphere * Random.value * 10f;
transformPositions[i] = Random.insideUnitSphere * Random.value * 10f;
attackRadiuses[i] = 1f + Random.value;
}
var watch = new Stopwatch();
watch.Start();
inRadius1 = V3Distance(targetPositions, transformPositions, attackRadiuses);
watch.Stop();
var v3DistanceElapsedMilliseconds = watch.ElapsedMilliseconds;
watch.Reset();
watch.Start();
inRadius2 = V1V2Magnitude(targetPositions, transformPositions, attackRadiuses);
watch.Stop();
var v1v2distanceElapsedMilliseconds = watch.ElapsedMilliseconds;
watch.Reset();
watch.Start();
inRadius3 = sqrMagnitude(targetPositions, transformPositions, attackRadiuses);
watch.Stop();
var sqrMagnitudeElapsedMilliseconds = watch.ElapsedMilliseconds;
watch.Reset();
watch.Start();
inRadius4 = V3Magnitude(targetPositions, transformPositions, attackRadiuses);
watch.Stop();
var V3MagnitudeElapsedMilliseconds = watch.ElapsedMilliseconds;
watch.Reset();
List<string> lines = new List<string>();
lines.Add($"{inRadius1} (Vector3.Distance(ms): {v3DistanceElapsedMilliseconds}");
lines.Add($"{inRadius2} ((v1-v2).Magnitude(ms): {v1v2distanceElapsedMilliseconds}");
lines.Add($"{inRadius3} (sqrMagnitude.Distance(ms): {sqrMagnitudeElapsedMilliseconds}");
lines.Add($"{inRadius4} (V3.Magnitude(ms): {V3MagnitudeElapsedMilliseconds}");
if (Time.frameCount > 10 && Application.isEditor)
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#endif
}
else if (Time.frameCount > 10)
{
Application.Quit();
}
File.WriteAllText("outputtext.txt", string.Join("\n", lines));
}
private int V3Distance(Vector3[] targetPositions, Vector3[] transformPositions, float[] attackRadiuses)
{
int inRadius = 0;
for (int i = 0; i < num; i++)
{
if (Vector3.Distance(targetPositions[i], transformPositions[i]) <= attackRadiuses[i])
{
inRadius++;
}
else
{
inRadius--;
}
}
return inRadius;
}
private int V3Magnitude(Vector3[] targetPositions, Vector3[] transformPositions, float[] attackRadiuses)
{
int inRadius = 0;
for (int i = 0; i < num; i++)
{
if (Vector3.Magnitude(targetPositions[i] - transformPositions[i]) <= attackRadiuses[i])
{
inRadius++;
}
else
{
inRadius--;
}
}
return inRadius;
}
private int V1V2Magnitude(Vector3[] targetPositions, Vector3[] transformPositions, float[] attackRadiuses)
{
int inRadius = 0;
for (int i = 0; i < num; i++)
{
if ((targetPositions[i] - transformPositions[i]).magnitude <= attackRadiuses[i])
{
inRadius++;
}
else
{
inRadius--;
}
}
return inRadius;
}
private int sqrMagnitude(Vector3[] targetPositions, Vector3[] transformPositions, float[] attackRadiuses)
{
int inRadius = 0;
for (int i = 0; i < num; i++)
{
if ((targetPositions[i] - transformPositions[i]).sqrMagnitude <= attackRadiuses[i] * attackRadiuses[i])
{
inRadius++;
}
else
{
inRadius--;
}
}
return inRadius;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment