-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Knucleotide benchmark heavily uses Dictionary lookups. It uses the following struct as key into hash table
struct ByteString
{
public byte[] Array
public int Start;
public int Length;
public override int GetHashCode()
{
int hc = 0;
for (int i = 0; i < Length; i++)
hc = hc * 31 + Array[Start + i];
return hc;
}
public bool Equals(ByteString other)
{
if (Length != other.Length) return false;
for (int i = 0; i < Length; i++)
if (Array[Start+i] != other.Array[other.Start+i]) return false;
return true;
}
}
Call Chain:
Dictionary.TryGetValue() --> FindEntry() --> calls GetHashCode() and Equals() methods on ByteString.
In case of Equals() or GetHashCode() methods, ByteString accessed is either "thisptr" or argument passed to the method. Struct args on Windows are considered implicitly by-ref and hence struct fields get accessed through an indirection on a byref. Legacy JIT64 was able to loop hoist this.Array, this.Array.Length, this.Start, other.Array, other.Array.Length and other.Start by recognizing them as loop invariant. This shows up as execution perf difference between RyuJIT vs Legacy Jit64.
category:cq
theme:loop-opt
skill-level:expert
cost:medium