-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Optimize DateTime.Year/.DayOfYear properties; fix comments #73277
Conversation
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsIt is continuation of #72712 After we split
It will further improve Also corrected comments and var names after previous commit. Thanks again to Cassio Neri & Lorenz Schneider for their brilliant work!
|
Some remarks and suggestions.
My C implementation of version 3 seems to work fine (*) as can be seen here. Please, test and measure (and possibly fix) the C# implementation. Perhaps, your PR #72712 can also be improved by taking point 1 above into consideration. (*) Unless I got wrong the epoch that .NET uses. I assumed it's 01/01/0001. |
I confirm perfrormance gain when using unsigned arithmetic and mul/div optimization instead of
Last 3 implementations are equal to the accuracy of the measurement.
Pros for
Pros for your MUL/DIV suggestion:
I have changed
You are right. Epoch date for
Its look like all division operations are unsigned in that PR (excluding those replaced in this PR). I followed this rule (point 1.). Thank you. I really appreciate your help to improve the code! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good stuff.
Great follow up! We should merge this in the coming week so it is in .NET 7. (There is no error value in your benchmark table - are you using Benchmark .NET and somehow it is only running one iteration?) Would you consider adding some randomized test cases for DayOfYear, as mentioned in the other PR? I am on vacation and can't look at the moment but IIRC it was the one that did not have such coverage. |
Yes, I used Benchmark.NET with following pattern:
Internal loop is to cover full range of DateTime values.
I will look what can be improved in tests. |
Instead of randomized dates, what about a kind of exhaustive test? It can loop through values of The above is not exhaustive because it only considers one tick per day (ignoring intraday ticks). However, the only think it misses to test is the conversion from ticks to ticks-per-day performed behind the scenes by |
I have to learn test conventions of dotnet project, but may be exhaustive test is very expensive, because millions tests run on every commit into repo. Added quick random |
For the test, we use a fixed seed for reproducibility. Then of course we will need to test more then one value. Eg use N random values or perhaps better to cover the epoch with random strides? With respect to exhaustive a test like this probably should not take longer than say 50ms? Depending on other tests running in parallel, it may not end up making the whole library run for any longer. |
Changed Added |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good if the tests pass!
If you feel like it you could follow up with a PR into dotnet/performance that protects the improvements. |
The tests cancel by timeout. I see it is 200 ms. |
I am not aware of a general test timeout mechanism beyond the one for the test library as a while (which is very large, something like an hour I believe) Occasionally the test machines are exceptionally slow. I have seen tests that take 0.5 sec or less locally seem to take 20 sec. This can particularly happen on constrained hardware such as phone and simulators. They should not fail in such a case so where a test needs a timeout we often use 30 seconds so long as the test is typically much faster. |
Failures are unrelated, I will have to open an issue later. Merging. Thanks! |
Are you interested in offering any other contributions @SergeiPavlov ? We have many marked up for grabs, or perhaps there is some other area where you are a potential optimization that interests you. |
Usually I contribute into areas which can impact performance of applications I develop as my main job. Of course I'd be glad to improve other places when I face with them. |
It is continuation of #72712
After we split
.GetDatePart()
method into separate properties (thank @danmoseley for the idea) we can calculateDateTime.Year
&DateTime.DayOfYear
more efficiently.No need for shift to
3/1/0000
base date, used for month/day calculation.It will further improve
DateTime.Now
, because its implementation uses.Year
.Apparently 'July 2022 optimization DateTime.DayOfYear' was an anti-optimization. It used
IsLeapYear()
with unnecessary year range checks. I missed its benchmarking while checked only.Year
,.Month
,.Day
,.GetDate()
Also:
EafMultiplier
,EafDivider
used over EAF calculationsThanks again to Cassio Neri & Lorenz Schneider for their brilliant work!