Replies: 2 comments
-
/cc: @EgorBo |
Beta Was this translation helpful? Give feedback.
0 replies
-
For comparison static bool StartsWith(string s) => s is { } && (s.StartsWith("ABCD", Ordinal) || s.StartsWith("EFGH", Ordinal)); Program.<<Main>$>g__StartsWith|0_0(System.String)
L0000: test rcx, rcx
L0003: je short L003c
L0005: cmp dword ptr [rcx+8], 4
L0009: jl short L0033
L000b: mov rax, [rcx+0xc]
L000f: mov rcx, 0x44004300420041
L0019: cmp rax, rcx
L001c: je short L0036
L001e: mov rcx, 0x48004700460045
L0028: cmp rax, rcx
L002b: sete al
L002e: movzx eax, al
L0031: jmp short L0035
L0033: xor eax, eax
L0035: ret
L0036: mov eax, 1
L003b: ret
L003c: xor eax, eax
L003e: ret And static bool EndsWith(string s) => s is { } && (s.EndsWith("ABCD", Ordinal) || s.EndsWith("EFGH", Ordinal));
static bool EndsWith2(string s) => s is { Length: >= 4 } && (s.EndsWith("ABCD", Ordinal) || s.EndsWith("EFGH", Ordinal)); Program.<<Main>$>g__EndsWith|0_1(System.String)
L0000: push rbx
L0001: sub rsp, 0x20
L0005: mov rbx, rcx
L0008: test rbx, rbx
L000b: je short L0066
L000d: mov rdx, 0x1e280070938
L0017: mov rdx, [rdx]
L001a: mov rcx, rbx
L001d: mov r8d, 4
L0023: mov rax, 0x7ffcbcde6130
L002d: call qword ptr [rax]
L002f: test eax, eax
L0031: jne short L005b
L0033: mov rdx, 0x1e280070968
L003d: mov rdx, [rdx]
L0040: mov rcx, rbx
L0043: mov r8d, 4
L0049: mov rax, 0x7ffcbcde6130
L0053: add rsp, 0x20
L0057: pop rbx
L0058: jmp qword ptr [rax]
L005b: mov eax, 1
L0060: add rsp, 0x20
L0064: pop rbx
L0065: ret
L0066: xor eax, eax
L0068: add rsp, 0x20
L006c: pop rbx
L006d: ret
Program.<<Main>$>g__EndsWith2|0_2(System.String)
L0000: push rbx
L0001: sub rsp, 0x20
L0005: mov rbx, rcx
L0008: test rbx, rbx
L000b: je short L006c
L000d: cmp dword ptr [rbx+8], 4
L0011: jl short L006c
L0013: mov rdx, 0x1e280070938
L001d: mov rdx, [rdx]
L0020: mov rcx, rbx
L0023: mov r8d, 4
L0029: mov rax, 0x7ffcbcde6130
L0033: call qword ptr [rax]
L0035: test eax, eax
L0037: jne short L0061
L0039: mov rdx, 0x1e280070968
L0043: mov rdx, [rdx]
L0046: mov rcx, rbx
L0049: mov r8d, 4
L004f: mov rax, 0x7ffcbcde6130
L0059: add rsp, 0x20
L005d: pop rbx
L005e: jmp qword ptr [rax]
L0061: mov eax, 1
L0066: add rsp, 0x20
L006a: pop rbx
L006b: ret
L006c: xor eax, eax
L006e: add rsp, 0x20
L0072: pop rbx
L0073: ret |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
When looking at the generated ASM for
M1
,s
is null checked a single time, but itsLength
is checked before each comparison with the constant strings.As all the constant strings are of length 4, we can make a single length check on
s
.Doing this generates ASM where we only have a single null check and a single length check.
It is possible for the JIT to perform a similar reasoning?
// * Summary *
BenchmarkDotNet v0.13.12, Windows 10 (10.0.19045.4291/22H2/2022Update)
Intel Core i7-10750H CPU 2.60GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK 9.0.100-preview.3.24204.13
[Host] : .NET 9.0.0 (9.0.24.17209), X64 RyuJIT AVX2
DefaultJob : .NET 9.0.0 (9.0.24.17209), X64 RyuJIT AVX2
And similarly when doing unrolled case-insensitive string comparisons
M3
has 6or
, whileM4
has a single.Beta Was this translation helpful? Give feedback.
All reactions