Unity version: 2023.2.11f1
Test Framework version: 1.3.9
Performance testing API: 3.0.3
I’ve been doing some performance benchmarking and am getting results that don’t quite make sense. Overall, it seemed that the values recorded by the benchmarking framework are much higher than they should be.
I decided to build a very simple test measuring the cost of a dictionary lookup and was shocked at the results. First, here is the test code:
[Test, Performance]
public void BenchmarkResolve_DictonaryLookup()
{
const int WarmupCount = 1000;
const int Measurements = 1000;
const int Iterations = 1000;
const string Key = "Test";
SampleGroup sampleGroup = new SampleGroup("Time", SampleUnit.Nanosecond);
Dictionary<string, int> dict = new();
dict.Add(Key, 10);
Measure.Method(() =>
{
dict.TryGetValue(Key, out int value);
})
.SampleGroup(sampleGroup)
.WarmupCount(WarmupCount)
.MeasurementCount(Measurements)
.IterationsPerMeasurement(Iterations)
.Run();
}
The results from running this test are as follows (all numbers are in nanoseconds):
Deviation: 0.27 ns
SD: 5139.22 ns
Median: 18800 ns
Min: 18700 ns
Max: 98400 ns
The results were collected in Editor, in Release mode, and were a PlayMode test (I get similar results with EditMode tests).
I don’t think these results are correct. A dictionary lookup should be on the order of 200-250 nanoseconds maximum, not almost 20000. Here is a link to an article of someone using BenchmarkDotNet to sample a dictionary lookup with a string key length of 200 characters, which comes in at 214.9 nanoseconds. I understand that there are differences between Mono and the versions of .NET tested in that article, but 4.8.2 is not far off from the 4.7.2 that Mono is based off of and I can’t imagine the differences between those version are so drastic that one is nearly x100 slower than the other.
It’s much more likely that the performance benchmarking tool is either displaying incorrect data or is errantly capturing the performance overhead of other systems that aren’t related to what is being measured. Indeed, the suspicious Max value of 98400 ns seem to be caused by spikes that I doubt are related to the actual performance cost of a dictionary lookup. I’m not running anything else within Unity during these tests so whatever is being captured must be coming from the engine itself.
Am I using the tool wrong? Is my understanding of the data wrong? Is my understanding of how fast a dictionary lookup should be wrong? I am most certainly willing to accept that there’s some user error on my part here I’m just having difficulty seeing it. Any insight into this problem would be appreciated.