Skip to content

Conversation

@DavidKarlas
Copy link
Contributor

All this changes are to internal methods which are later called by other public methods which correctly call ToLocalTime for local time "overloads".
Performance hit is most visible for application which doesn't need to load local timezone information which takes ~30ms on 2016 MacBook Pro.

I tried to create unit tests for File.GetLastWriteTime/Utc, but problem is that values get converted correctly.
Test that I added has a problem, it will pass even if logic regresses on machine with timezone+0.

All this changes are to internal methods which are later called by other public methods which correctly call `ToLocalTime` for local time "overloads".
Performance hit is most visible for application which doesn't need to load local timezone information which takes ~30ms on 2016 MacBook Pro.
@ghost ghost added the area-System.IO label May 21, 2021
@ghost
Copy link

ghost commented May 21, 2021

Tagging subscribers to this area: @carlossanlop
See info in area-owners.md if you want to be subscribed.

Issue Details

All this changes are to internal methods which are later called by other public methods which correctly call ToLocalTime for local time "overloads".
Performance hit is most visible for application which doesn't need to load local timezone information which takes ~30ms on 2016 MacBook Pro.

I tried to create unit tests for File.GetLastWriteTime/Utc, but problem is that values get converted correctly.
Test that I added has a problem, it will pass even if logic regresses on machine with timezone+0.

Author: DavidKarlas
Assignees: -
Labels:

area-System.IO

Milestone: -

@adamsitnik
Copy link
Member

Hi @DavidKarlas

Could you please contribute benchmarks that excercise the methods that you are trying to optimize to dotnet/performance and use corerun to show us the exact difference?

EnsureCachesInitialized(path, continueOnError);
if (!_exists)
return DateTimeOffset.FromFileTime(0);
return new DateTimeOffset(DateTime.FromFileTimeUtc(0));
Copy link
Member

@stephentoub stephentoub May 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a breaking change? Previously the DateTime that was returned would have had a Kind == Local, but now it's going to have a Kind == Utc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore that... I was reading it as DateTime rather than DateTimeOffset.

Copy link
Member

@stephentoub stephentoub May 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But... it's still a semantic change... won't the returned DateTimeOffset now have a different value than it did previously, with a different offset? Or it doesn't matter because this method is only used internally and the call sites ensure the right thing happens?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is called from 2 locations:

  1. FileSystemEntry.CreationTimeUtc which by it's name already expects DateTimeOffset to be Utc, this is what added unit test ensures.
  2. FileSystemInfo.CreationTimeCore which is only called from FileSystemInfo.CreationTimeUtc, notice that FileSystemInfo.CreationTime calls FileSystemInfo.CreationTimeUtc.ToLocalTime()

I assumed FileSystemInfo.CreationTimeCore on Windows also returns UTC, but while investigating for this answer I noticed that it calls FILE_TIME.ToDateTimeOffset which is also performing ToLocalTime which I think is as unnecessary on Windows as on Unix.

I will change Windows as well and write Performance test as requested by @adamsitnik.

@DavidKarlas
Copy link
Contributor Author

Hi @DavidKarlas

Could you please contribute benchmarks that excercise the methods that you are trying to optimize to dotnet/performance and use corerun to show us the exact difference?

I will add performance tests thank you for pointing that out... I will work on this later this week.

@jeffhandley
Copy link
Member

@DavidKarlas I merged from main to resolve the merge conflicts.

@DavidKarlas
Copy link
Contributor Author

Thank you for doing that, sorry I dropped a ball a bit on this...

I ran into a bit a problem few weeks back... MicroBenchmarks cant capture this fix since they have warmup and repetition, because there isnt much saving there, savings are on first run of app(which is important for CLI tools), because with this change it doesnt need to load Timezones data.

@jeffhandley
Copy link
Member

No worries, @DavidKarlas! That's tricky; I'm not sure how to capture good data for that. I'll have to rely on @adamsitnik's signoff/guidance.

@DavidKarlas
Copy link
Contributor Author

Maybe I just need Scenario test, but there arent many examples, 30ms difference is very noticable...

@jeffhandley
Copy link
Member

@adamsitnik Could you review this before our Preview 7 snap please?

Copy link
Member

@jozkee jozkee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes sense to me, should we prioritize it for 6.0? Seems to me that only missing requirement was benchmark results for warmup time, is that correct? Even without the results, it looks reasonable to avoid caching something when is not really needed.

@jeffhandley
Copy link
Member

@adamsitnik This PR is assigned to you for follow-up/decision before the RC1 snap. @jozkee, feel free to self-assign if you'd like to drive it instead though.

Copy link
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, big thanks for the PR and appologies for the delay @DavidKarlas

@adamsitnik adamsitnik merged commit f03c995 into main Aug 10, 2021
@adamsitnik adamsitnik deleted the dev/davkar/fixPerfGetLastWriteTimeUtcOnUnix branch August 10, 2021 08:12
@adamsitnik adamsitnik added this to the 6.0.0 milestone Aug 10, 2021
@DavidKarlas
Copy link
Contributor Author

Thank you all for reviewing and merging <3

@ghost ghost locked as resolved and limited conversation to collaborators Sep 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants