-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Impove StringComparer.OrdinalIgnoreCase.Equals #87006
Conversation
Unfortunately, we hit here exactly the same problem that we faced with |
The most common use of these APIs is for non-constant strings in collections or sorting. Are there any changes in the codegen or perf due to this change in the common case? |
Ideally, it should be exactly the same codegen, but currently it is not, to have the same codegen we need to make |
runtime/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs Lines 704 to 742 in 9c4d51c
CheckStringComparison should also be folded to no-op.
Presumably, this API is mostly called with a constant string comparison mode? |
@jkotas so do you have any preference of what we can do here?
https://grep.app/search?q=StringComparer.OrdinalIgnoreCase.Equals |
I do not think we would want to mark the current implementation as aggressive inline. It would eat the inlining budget too fast. This API is used a lot and it is not unusual to see it called multiple times from a single method. I think it may be ok to make an assumption that this API is almost always called with a constant StringComparison argument and refactor the implementation to optimize for this case: The public method that has just a switch over There are number of methods in CoreLib that take StringComparison and where this optimization can be potentially applied to. |
I think it would be a regression on average. I would expect that these comparers are much more likely to be used with collections. I think that the examples from your query are minority. In fact, we may want to have an analyzer that recommends replacing calls of virtual Comparer to more direct string.Equals calls that are smaller and easier to optimize. |
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsCloses #86999 Unifies static bool Test(string s) =>
StringComparer.OrdinalIgnoreCase.Equals(s, "hello"); ; Assembly listing for method Program:Test(System.String):bool
test rcx, rcx
je SHORT G_M18217_IG05
cmp dword ptr [rcx+08H], 5
jne SHORT G_M18217_IG05
mov rax, 0x20002000200020
or rax, qword ptr [rcx+0CH]
mov rdx, 0x6C006C00650068
xor rax, rdx
mov edx, dword ptr [rcx+12H]
or edx, 0x200020
xor edx, 0x6F006C
or rax, rdx
sete al
movzx rax, al
jmp SHORT G_M18217_IG06
G_M18217_IG05: ;; offset=0040H
xor eax, eax
G_M18217_IG06: ;; offset=0042H
movzx rax, al
ret
; Total bytes of code 70
|
Ok, I agree. As I don't see how we can make that |
Closes #86999
Unifies
OrdinalIgnoreCaseComparer
withOrdinalCaseSensitiveComparer
to just callString
's APIs.