Skip to content

Instantly share code, notes, and snippets.

@mattbenic
Created July 18, 2016 07:31
Show Gist options
  • Save mattbenic/c5fa558ee129c5683cb53ce42fe75d41 to your computer and use it in GitHub Desktop.
Save mattbenic/c5fa558ee129c5683cb53ce42fe75d41 to your computer and use it in GitHub Desktop.
Relative loop performance tests in Unity and VS compiled code
// Included directly in Unity
using System.Collections.Generic;
using System.Diagnostics;
public static class CompiledInUnity
{
private const int ArrayLength = 20;
private const long BatchSize = 10000000;
private static float[] CreateFloatArray()
{
float[] array = new float[ArrayLength];
for (int i = 0; i < ArrayLength; ++i)
{
array[i] = i;
}
return array;
}
public static long FloatArrayForWithCachedLength()
{
float[] arr = CreateFloatArray();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
int len = arr.Length;
for (int j = 0; j < len; ++j)
f += arr[j];
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatArrayForWithoutCachedLength()
{
float[] arr = CreateFloatArray();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
for (int j = 0; j < arr.Length; ++j)
f += arr[j];
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatArrayForeach()
{
float[] arr = CreateFloatArray();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
foreach (float v in arr)
f += v;
}
return stopwatch.ElapsedMilliseconds;
}
private static List<float> CreateFloatList()
{
List<float> list = new List<float>(ArrayLength);
for (int i = 0; i < ArrayLength; ++i)
{
list.Add(i);
}
return list;
}
public static long FloatListForWithCachedLength()
{
List<float> list = CreateFloatList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
int len = list.Count;
for (int j = 0; j < len; ++j)
f += list[j];
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatListForWithoutCachedLength()
{
List<float> list = CreateFloatList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
for (int j = 0; j < list.Count; ++j)
f += list[j];
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatListForeach()
{
List<float> list = CreateFloatList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
foreach (float v in list)
f += v;
}
return stopwatch.ElapsedMilliseconds;
}
private static List<FloatObj> CreateFloatObjList()
{
List<FloatObj> list = new List<FloatObj>(ArrayLength);
for (int i = 0; i < ArrayLength; ++i)
{
list.Add(new FloatObj { Value = i });
}
return list;
}
public static long FloatObjListForWithCachedLength()
{
List<FloatObj> list = CreateFloatObjList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
int len = list.Count;
for (int j = 0; j < len; ++j)
f += list[j].Value;
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatObjListForWithoutCachedLength()
{
List<FloatObj> list = CreateFloatObjList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
for (int j = 0; j < list.Count; ++j)
f += list[j].Value;
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatObjListForeach()
{
List<FloatObj> list = CreateFloatObjList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
foreach (FloatObj obj in list)
f += obj.Value;
}
return stopwatch.ElapsedMilliseconds;
}
private class FloatObj
{
public float Value;
}
}
// In a separate dll project, set up to compile to different dlls in release and debug. Manually rename class to CompiledInVSRelease/Debug based on the configuration
using System.Collections.Generic;
using System.Diagnostics;
public static class CompiledInVSRelease
{
private const int ArrayLength = 20;
private const long BatchSize = 10000000;
private static float[] CreateFloatArray()
{
float[] array = new float[ArrayLength];
for (int i = 0; i < ArrayLength; ++i)
{
array[i] = i;
}
return array;
}
public static long FloatArrayForWithCachedLength()
{
float[] arr = CreateFloatArray();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
int len = arr.Length;
for (int j = 0; j < len; ++j)
f += arr[j];
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatArrayForWithoutCachedLength()
{
float[] arr = CreateFloatArray();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
for (int j = 0; j < arr.Length; ++j)
f += arr[j];
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatArrayForeach()
{
float[] arr = CreateFloatArray();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
foreach (float v in arr)
f += v;
}
return stopwatch.ElapsedMilliseconds;
}
private static List<float> CreateFloatList()
{
List<float> list = new List<float>(ArrayLength);
for (int i = 0; i < ArrayLength; ++i)
{
list.Add(i);
}
return list;
}
public static long FloatListForWithCachedLength()
{
List<float> list = CreateFloatList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
int len = list.Count;
for (int j = 0; j < len; ++j)
f += list[j];
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatListForWithoutCachedLength()
{
List<float> list = CreateFloatList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
for (int j = 0; j < list.Count; ++j)
f += list[j];
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatListForeach()
{
List<float> list = CreateFloatList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
foreach (float v in list)
f += v;
}
return stopwatch.ElapsedMilliseconds;
}
private static List<FloatObj> CreateFloatObjList()
{
List<FloatObj> list = new List<FloatObj>(ArrayLength);
for (int i = 0; i < ArrayLength; ++i)
{
list.Add(new FloatObj { Value = i });
}
return list;
}
public static long FloatObjListForWithCachedLength()
{
List<FloatObj> list = CreateFloatObjList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
int len = list.Count;
for (int j = 0; j < len; ++j)
f += list[j].Value;
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatObjListForWithoutCachedLength()
{
List<FloatObj> list = CreateFloatObjList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
for (int j = 0; j < list.Count; ++j)
f += list[j].Value;
}
return stopwatch.ElapsedMilliseconds;
}
public static long FloatObjListForeach()
{
List<FloatObj> list = CreateFloatObjList();
float f;
Stopwatch stopwatch = Stopwatch.StartNew();
f = 0;
for (int i = 0; i < BatchSize; ++i)
{
foreach (FloatObj obj in list)
f += obj.Value;
}
return stopwatch.ElapsedMilliseconds;
}
private class FloatObj
{
public float Value;
}
}
// Add to an object in Unity, then play
using System;
using System.Text;
using UnityEngine;
public class Tester : MonoBehaviour
{
void RunTest(Func<long> test, StringBuilder builder)
{
builder.AppendFormat("{0}.{1}:\t{2}\n",
test.Method.DeclaringType.Name,
test.Method.Name,
test());
}
void Start()
{
StringBuilder builder = new StringBuilder();
RunTest(CompiledInUnity.FloatArrayForWithCachedLength, builder);
RunTest(CompiledInUnity.FloatArrayForWithoutCachedLength, builder);
RunTest(CompiledInUnity.FloatArrayForeach, builder);
RunTest(CompiledInUnity.FloatListForWithCachedLength, builder);
RunTest(CompiledInUnity.FloatListForWithoutCachedLength, builder);
RunTest(CompiledInUnity.FloatListForeach, builder);
RunTest(CompiledInUnity.FloatObjListForWithCachedLength, builder);
RunTest(CompiledInUnity.FloatObjListForWithoutCachedLength, builder);
RunTest(CompiledInUnity.FloatObjListForeach, builder);
builder.AppendLine("------------------------------------------------");
RunTest(CompiledInVSDebug.FloatArrayForWithCachedLength, builder);
RunTest(CompiledInVSDebug.FloatArrayForWithoutCachedLength, builder);
RunTest(CompiledInVSDebug.FloatArrayForeach, builder);
RunTest(CompiledInVSDebug.FloatListForWithCachedLength, builder);
RunTest(CompiledInVSDebug.FloatListForWithoutCachedLength, builder);
RunTest(CompiledInVSDebug.FloatListForeach, builder);
RunTest(CompiledInVSDebug.FloatObjListForWithCachedLength, builder);
RunTest(CompiledInVSDebug.FloatObjListForWithoutCachedLength, builder);
RunTest(CompiledInVSDebug.FloatObjListForeach, builder);
builder.AppendLine("------------------------------------------------");
RunTest(CompiledInVSRelease.FloatArrayForWithCachedLength, builder);
RunTest(CompiledInVSRelease.FloatArrayForWithoutCachedLength, builder);
RunTest(CompiledInVSRelease.FloatArrayForeach, builder);
RunTest(CompiledInVSRelease.FloatListForWithCachedLength, builder);
RunTest(CompiledInVSRelease.FloatListForWithoutCachedLength, builder);
RunTest(CompiledInVSRelease.FloatListForeach, builder);
RunTest(CompiledInVSRelease.FloatObjListForWithCachedLength, builder);
RunTest(CompiledInVSRelease.FloatObjListForWithoutCachedLength, builder);
RunTest(CompiledInVSRelease.FloatObjListForeach, builder);
Debug.Log(builder.ToString());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment