-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
DateTime.DaysInMonth minor performance tweaks #91103
Comments
Can you please share your benchmark? |
Sure
Its almost 10 to 1 Ratio in debug mode. |
private static ReadOnlySpan<byte> P => new byte[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private static readonly byte[] F = new byte[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
public byte Property(int i) => P[i];
public byte Field(int i) => F[i]; ; Method Program:Property(int):ubyte:this
G_M000_IG01: ;; offset=0000H
4883EC28 sub rsp, 40
G_M000_IG02: ;; offset=0004H
83FA0C cmp edx, 12
7315 jae SHORT G_M000_IG04
8BC2 mov eax, edx
48BAF02A32617F020000 mov rdx, 0x27F61322AF0
0FB60410 movzx rax, byte ptr [rax+rdx]
G_M000_IG03: ;; offset=0019H
4883C428 add rsp, 40
C3 ret
G_M000_IG04: ;; offset=001EH
E8AD63C35F call CORINFO_HELP_RNGCHKFAIL
CC int3 ; Method Program:Field(int):ubyte:this
G_M000_IG01: ;; offset=0000H
56 push rsi
4883EC20 sub rsp, 32
8BF2 mov esi, edx
G_M000_IG02: ;; offset=0007H
48B9A8CF943DFE7F0000 mov rcx, 0x7FFE3D94CFA8
BA04000000 mov edx, 4
E805D1AE5F call CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE
48B8381FC07A8B020000 mov rax, 0x28B7AC01F38
488B00 mov rax, gword ptr [rax]
3B7008 cmp esi, dword ptr [rax+08H]
730D jae SHORT G_M000_IG04
8BD6 mov edx, esi
0FB6441010 movzx rax, byte ptr [rax+rdx+10H]
G_M000_IG03: ;; offset=0034H
4883C420 add rsp, 32
5E pop rsi
C3 ret
G_M000_IG04: ;; offset=003AH
E89163C15F call CORINFO_HELP_RNGCHKFAIL
CC int3 Codegen for field is worse than property. But it looks a bit weird for |
A raw main is the most common wrong way to measure performance. You should use BenchmarkDotNet to get correct measurement. On 7.0 I get this: public class Program
{
static void Main()
{
BenchmarkRunner.Run<Program>();
}
private static ReadOnlySpan<byte> P => new byte[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private static readonly byte[] F = new byte[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
[Params(2)]
public int Month { get; set; }
[Benchmark(Baseline = true)]
public byte Property() => P[Month];
[Benchmark]
public byte Field() => F[Month];
}
Do we have constant folding for this case? |
[MethodImpl(MethodImplOptions.NoInlining)]
private int GetMonth() => 2;
[Benchmark(Baseline = true)]
public byte Property() => P[GetMonth()];
[Benchmark]
public byte Field() => F[GetMonth()];
After inlining and constant folding disabled, the field is 24% slower than property. The runtime has special treatment for |
The "property" definitely is not an issue. Adding a leading zero element to |
|
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsHello, i did some performance testing and would propose changes to
Change to:
As the array is used as a lookup i would remove the
|
Try reversing the order of those two and you'll probably get the opposite result. |
I see, that's the problem. You should never benchmark debug mode. |
I did 6 release mode tests now, with different order, Fields always came out on top. 100000000 x 0,000002281506 ms, Total 228,15 ms, prop I guess after a while cpu cache kicks in... |
Ok I'll close. Thanks anyway @Charles113 for reporting. |
Hello, i did some performance testing and would propose changes to
DateTime.DaysInMonth(int year, int month)
Change to:
As the array is used as a lookup i would remove the
-1
Operation, also i thinkDaysInMonth365
should be a field instead of a property.I've noticed 5x Performance gains by doing lookups in a byte[] field instead of creating a new ReadOnlySpan every time through a property.
The text was updated successfully, but these errors were encountered: