Constant mod over chars can use a cheaper FastMod
#111.492 geöffnet am 16. Jan. 2025
Repository-Metriken
- Stars
- (17.886 Stars)
- PR-Merge-Metriken
- (Durchschn. Merge 12T 11h) (661 gemergte PRs in 30 T)
Beschreibung
#101001 added a faster variant of FastMod that SearchValues now uses when it knows that the value and divisor are both < 2^16 (i.e. chars).
Instead of
https://github.com/dotnet/runtime/blob/e71d737628c7b807aa12755dabe4eca40c40da7e/src/libraries/System.Private.CoreLib/src/System/Collections/HashHelpers.cs#L107
we can use
https://github.com/dotnet/runtime/blob/e71d737628c7b807aa12755dabe4eca40c40da7e/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMapState.cs#L223
Is it worth teaching the JIT to do something similar when it knows that values are in range?
int Mod1(char c) => c % 42;
int Mod2(char c) => (int)(((ulong)(102261127u * c) * 42) >> 32);
Test.Mod1(Char)
L0000: movzx eax, cx
L0003: mov ecx, eax
L0005: shr ecx, 1
L0007: imul rcx, 0x30c30c31
L000e: shr rcx, 0x22
L0012: imul ecx, 0x2a
L0015: sub eax, ecx
L0017: ret
Test.Mod2(Char)
L0000: movzx eax, cx
L0003: imul eax, 0x6186187
L0009: imul rax, 0x2a
L000d: shr rax, 0x20
L0011: ret