Last active
February 27, 2023 08:19
-
-
Save melodia-games/332af80ccad18f2a38b280ac43b2ba75 to your computer and use it in GitHub Desktop.
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 NUnit.Framework; | |
using UnityEngine; | |
using Unity.Mathematics; | |
using Unity.PerformanceTesting; | |
//TestRunnerでの実行結果 | |
//Index, Test Name, Version, SampleGroup Name, Unit, IncreaseIsBetter, Min, Max, Median, Average, StandardDeviation, Sum, Values, | |
//0,"Tests.TestPerformance.Test1",1,"Time","Millisecond",False,12438.2421,12881.16,12617.7891,12627.81142,150.106165086222,252556.2284,12490.3192,12588.2658,12568.1306,12473.9098,12459.1209,12438.2421,12725.6194,12778.6197,12863.0169,12465.9704,12707.7957,12857.5514,12617.7891,12767.8108,12777.468,12463.3161,12480.823,12524.9632,12881.16,12626.3363, | |
//1,"Tests.TestPerformance.Test2",1,"Time","Millisecond",False,15938.8846,16505.6858,16049.095,16124.86212,186.346231117262,322497.2424,16028.2931,15941.1558,16013.6348,15938.8846,15971.258,15980.1984,16112.7227,16049.095,16024.2381,15981.0402,16088.1292,16014.152,15968.7511,16127.7099,16291.8043,16505.6858,16435.8812999999,16485.3993,16417.4963,16121.7125, | |
//2,"Tests.TestPerformance.Test3",1,"Time","Millisecond",False,6260.8965,7737.7331,6503.6336,6659.80726,450.464388839386,133196.1452,6341.6141,6334.4877,6260.8965,6871.6594,7053.5972,7693.09649999999,7737.7331,7324.06090000001,6503.6336,6431.834,6311.18210000001,6319.2745,6399.9785,6298.7689,6317.64159999999,6379.83660000001,6594.13519999999,6547.22079999998,6531.54820000002,6943.94580000002, | |
//3,"Tests.TestPerformance.Test4",1,"Time","Millisecond",False,4141.6657,4450.3624,4291.6683,4291.56786,86.7366240374471,85831.3572,4291.6683,4308.0922,4141.6657,4229.3268,4248.4632,4202.32049999999,4333.6962,4399.51590000001,4349.0954,4247.6873,4266.8997,4301.83660000001,4391.0625,4335.88119999999,4171.9843,4280.39409999999,4288.29000000001,4450.3624,4443.3284,4149.7865, | |
//4,"Tests.TestPerformance.Test5",1,"Time","Millisecond",False,2346.7899,2508.5416,2413.6465,2414.701275,37.8625926773892,48294.0255,2346.7899,2432.7252,2361.459,2411.0666,2404.8773,2389.3895,2406.8033,2366.409,2382.0981,2448.4486,2449.3874,2449.3305,2508.5416,2381.76730000001,2421.8413,2460.1267,2418.8666,2443.31529999999,2397.1358,2413.6465, | |
namespace Tests | |
{ | |
public class TestHashCodePerformance | |
{ | |
const int Range = 1000; | |
const int WarmupCount = 5; | |
const int IterationsPerMeasurement = 10; | |
const int MeasurementCount = 20; | |
[Test] | |
[Performance] | |
public void Test1() => TestLoops((x, y) => new TestStruct1(x, y)); | |
[Test] | |
[Performance] | |
public void Test2() => TestLoops((x, y) => new TestStruct2(x, y)); | |
[Test] | |
[Performance] | |
public void Test3() => TestLoops((x, y) => new TestStruct3(x, y)); | |
[Test] | |
[Performance] | |
public void Test4() => TestLoops((x, y) => new TestStruct4(x, y)); | |
[Test] | |
[Performance] | |
public void Test5() => TestLoops((x, y) => new TestStruct5(x, y)); | |
void TestLoops<T>(Func<int, int, T> hashGetter) | |
{ | |
Measure.Method(() => { | |
// 衝突した状態での線形探索コストが計測できるように | |
// Keyをx,yのstructにしてHashCodeが衝突してもEqualsが異なる状態を作る | |
var map = new Dictionary<T, bool>(); | |
for (int x = -Range; x <= Range; x++) { | |
for (int y = -Range; y <= Range; y++) { | |
// Add | |
var key = hashGetter(x, y); | |
map.Add(key, true); | |
// Lookup | |
var value = map[key]; | |
// 最適化で消えないために適当な処理を入れる | |
Debug.Assert(value != !value); | |
} | |
} | |
}) | |
.WarmupCount(WarmupCount) | |
.IterationsPerMeasurement(IterationsPerMeasurement) | |
.MeasurementCount(MeasurementCount) | |
.Run(); | |
} | |
public readonly struct TestStruct1 : IEquatable<TestStruct1> | |
{ | |
public readonly int x; | |
public readonly int y; | |
public TestStruct1(int x, int y) | |
{ | |
this.x = x; | |
this.y = y; | |
} | |
public override int GetHashCode() | |
{ | |
return (x, y).GetHashCode(); | |
} | |
public bool Equals(TestStruct1 other) | |
{ | |
return x == other.x && y == other.y; | |
} | |
public override bool Equals(object other) | |
{ | |
if (other is TestStruct1 point) { | |
return Equals(point); | |
} | |
return false; | |
} | |
} | |
public readonly struct TestStruct2 : IEquatable<TestStruct2> | |
{ | |
public readonly int x; | |
public readonly int y; | |
public TestStruct2(int x, int y) | |
{ | |
this.x = x; | |
this.y = y; | |
} | |
public override int GetHashCode() | |
{ | |
return (17 * 23 + x) * 23 + y; | |
} | |
public bool Equals(TestStruct2 other) | |
{ | |
return x == other.x && y == other.y; | |
} | |
public override bool Equals(object other) | |
{ | |
if (other is TestStruct2 point) { | |
return Equals(point); | |
} | |
return false; | |
} | |
} | |
public readonly struct TestStruct3 : IEquatable<TestStruct3> | |
{ | |
public readonly int x; | |
public readonly int y; | |
public TestStruct3(int x, int y) | |
{ | |
this.x = x; | |
this.y = y; | |
} | |
public override int GetHashCode() | |
{ | |
return HashCode.Combine(x, y); | |
} | |
public bool Equals(TestStruct3 other) | |
{ | |
return x == other.x && y == other.y; | |
} | |
public override bool Equals(object other) | |
{ | |
if (other is TestStruct3 point) { | |
return Equals(point); | |
} | |
return false; | |
} | |
} | |
public readonly struct TestStruct4 : IEquatable<TestStruct4> | |
{ | |
public readonly int x; | |
public readonly int y; | |
public TestStruct4(int x, int y) | |
{ | |
this.x = x; | |
this.y = y; | |
} | |
public override int GetHashCode() | |
{ | |
return new int2(x, y).GetHashCode(); | |
} | |
public bool Equals(TestStruct4 other) | |
{ | |
return x == other.x && y == other.y; | |
} | |
public override bool Equals(object other) | |
{ | |
if (other is TestStruct4 point) { | |
return Equals(point); | |
} | |
return false; | |
} | |
} | |
public readonly struct TestStruct5 : IEquatable<TestStruct5> | |
{ | |
public readonly int x; | |
public readonly int y; | |
public TestStruct5(int x, int y) | |
{ | |
this.x = x; | |
this.y = y; | |
} | |
public override int GetHashCode() | |
{ | |
return (x << 16) ^ y; | |
} | |
public bool Equals(TestStruct5 other) | |
{ | |
return x == other.x && y == other.y; | |
} | |
public override bool Equals(object other) | |
{ | |
if (other is TestStruct5 point) { | |
return Equals(point); | |
} | |
return false; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment