Description
Description
I am using DateTime.Now
, DateTimeOffset.Now
and DateTime.Today
frequently in my app (I think many apps do).
Being aware that adding the timezone data to the DateTime/Offset structures comes with a performance penalty, I am trying to avoid them as much as possible and am using DateTime.UtcNow
& DateTimeOffset.UtcNow
instead. However, this is not always possible. On Android particularly, loading the time zone can significantly slow down startup performance and there has been work done before here to mitigate this problem: #71004
Data
Using this script and an empty Android .NET7 project I did some startup benchmarks. I started with an empty .NET for Android template.
- Added
Task.Delay(400).Wait();
to simulate startup work - no other changes: 713 ms - +
_ = DateTime.Now
to the MainActivity: 793 ms - +
_ = Task.Run(() => _ = DateTime.Today);
toMainApplication.OnCreate
: 714 ms
Tests were done on a Samsung A52.
Demo project used: AndroidApp.zip
Analysis
There is still a performance penalty (~70ms) when using timezone-dependent time during app startup. It can be mitigated by triggering the timezone info retrieval process early in the startup process on a different thread.
Would it be possible to trigger this process automatically during app startup so the timezone information is available immediately the first DateTimeOffset.Now
et al is called?
Also, if DateTime.Today
is called, the timezone offset does not need to be known. It can be calculated very fast (~1-2ms) using Android APIs:
ar cal = Java.Util.Calendar.Instance;
var today = new DateTime(
cal.Get(Java.Util.CalendarField.Year),
cal.Get(Java.Util.CalendarField.Month) + 1,
cal.Get(Java.Util.CalendarField.DayOfMonth));
Would it be possible to calculate & cache a DateTime.Today
-placeholder using the code above and return it from DateTime.Today
-calls it while the timezone file is loaded and parsed in the background? That way I could use a penalty-free DateTime.Today
right away when starting the app.