Last active
January 6, 2020 09:09
-
-
Save TheSpydog/a645a12527da655ade7c8f0721ff179b to your computer and use it in GitHub Desktop.
C# Lookup Perf Test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Runtime.InteropServices; | |
using System.Diagnostics; | |
namespace LookupTest | |
{ | |
class MainClass | |
{ | |
class MyTestClass | |
{ | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
internal struct MyStruct : IEquatable<MyStruct> | |
{ | |
readonly ulong a; | |
readonly ulong b; | |
public MyStruct(ulong a, ulong b) | |
{ | |
this.a = a; | |
this.b = b; | |
} | |
public override string ToString() | |
{ | |
return Convert.ToString((long) a, 2).PadLeft(64, '0') + | |
Convert.ToString((long) b, 2).PadLeft(64, '0'); | |
} | |
bool IEquatable<MyStruct>.Equals(MyStruct hash) | |
{ | |
return a == hash.a && b == hash.b; | |
} | |
public override bool Equals(object obj) | |
{ | |
if (obj == null || obj.GetType() != GetType()) | |
{ | |
return false; | |
} | |
MyStruct hash = (MyStruct) obj; | |
return a == hash.a && b == hash.b; | |
} | |
public override int GetHashCode() | |
{ | |
int i1 = (int) (a ^ (a >> 32)); | |
int i2 = (int) (b ^ (b >> 32)); | |
return i1 + i2; | |
} | |
} | |
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 128)] | |
struct MyOldStruct : IEquatable<MyOldStruct> | |
{ | |
readonly int i1; | |
readonly int i2; | |
readonly int i3; | |
readonly int i4; | |
public MyOldStruct(int i1, int i2, int i3, int i4) | |
{ | |
this.i1 = i1; | |
this.i2 = i2; | |
this.i3 = i3; | |
this.i4 = i4; | |
} | |
bool IEquatable<MyOldStruct>.Equals(MyOldStruct hash) | |
{ | |
return i1 == hash.i1 && i2 == hash.i2 && i3 == hash.i3 && i4 == hash.i4; | |
} | |
public override bool Equals(object obj) | |
{ | |
if (obj == null || obj.GetType() != GetType()) | |
{ | |
return false; | |
} | |
MyOldStruct hash = (MyOldStruct) obj; | |
return i1 == hash.i1 && i2 == hash.i2 && i3 == hash.i3 && i4 == hash.i4; | |
} | |
public override int GetHashCode() | |
{ | |
return unchecked(i1 + i2 + i3 + i4); | |
} | |
} | |
public static int TEST_RUNS; | |
public static void Main(string[] args) | |
{ | |
if (args.Length < 1) | |
{ | |
Console.WriteLine("Usage: lookuptest.exe <iterations>"); | |
return; | |
} | |
TEST_RUNS = Int32.Parse(args[0].ToString()); | |
Console.WriteLine("Running int test..."); | |
RunIntKeyTest(); | |
Console.WriteLine("Running old struct test..."); | |
RunOldStructKeyTest(); | |
Console.WriteLine("Running new struct test..."); | |
RunStructKeyTest(); | |
} | |
static void RunIntKeyTest() | |
{ | |
Dictionary<int, MyTestClass> dict = new Dictionary<int, MyTestClass>(); | |
for (int i = 0; i < TEST_RUNS; i += 1) | |
{ | |
dict.Add(i, new MyTestClass()); | |
} | |
Stopwatch stopWatch = new Stopwatch(); | |
stopWatch.Start(); | |
for (int i = 0; i < TEST_RUNS; i += 1) | |
{ | |
MyTestClass blah = dict[i]; | |
} | |
stopWatch.Stop(); | |
TimeSpan ts = stopWatch.Elapsed; | |
// Format and display the TimeSpan value. | |
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", | |
ts.Hours, ts.Minutes, ts.Seconds, | |
ts.Milliseconds / 10); | |
Console.WriteLine("RunTime " + elapsedTime); | |
} | |
static void RunStructKeyTest() | |
{ | |
Dictionary<MyStruct, MyTestClass> structDict = new Dictionary<MyStruct, MyTestClass>(); | |
for (ulong i = 0; i < (ulong) TEST_RUNS; i += 1) | |
{ | |
MyStruct s = new MyStruct(i, 0); | |
structDict.Add(s, new MyTestClass()); | |
} | |
Console.WriteLine("Finished building struct dict! Moving on..."); | |
Stopwatch stopWatch = new Stopwatch(); | |
stopWatch.Start(); | |
for (ulong i = 0; i < (ulong) TEST_RUNS; i += 1) | |
{ | |
MyStruct s = new MyStruct(i, 0); | |
MyTestClass blah = structDict[s]; | |
} | |
stopWatch.Stop(); | |
TimeSpan ts = stopWatch.Elapsed; | |
// Format and display the TimeSpan value. | |
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", | |
ts.Hours, ts.Minutes, ts.Seconds, | |
ts.Milliseconds / 10); | |
Console.WriteLine("RunTime " + elapsedTime); | |
} | |
static void RunOldStructKeyTest() | |
{ | |
Dictionary<MyOldStruct, MyTestClass> structDict = new Dictionary<MyOldStruct, MyTestClass>(); | |
for (int i = 0; i < TEST_RUNS; i += 1) | |
{ | |
MyOldStruct s = new MyOldStruct(i, 0, i, 0); | |
structDict.Add(s, new MyTestClass()); | |
} | |
Console.WriteLine("Finished building struct dict! Moving on..."); | |
Stopwatch stopWatch = new Stopwatch(); | |
stopWatch.Start(); | |
for (int i = 0; i < TEST_RUNS; i += 1) | |
{ | |
MyOldStruct s = new MyOldStruct(i, 0, i, 0); | |
MyTestClass blah = structDict[s]; | |
} | |
stopWatch.Stop(); | |
TimeSpan ts = stopWatch.Elapsed; | |
// Format and display the TimeSpan value. | |
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", | |
ts.Hours, ts.Minutes, ts.Seconds, | |
ts.Milliseconds / 10); | |
Console.WriteLine("RunTime " + elapsedTime); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment