Repository navigation
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Preamble: I'm just another consumer of TimeZoneNames, i.e. I have no authority here. That's a clever use of a source-generator! I tried getting some numbers to see the pros/cons of this approach. file size of nupkg:
file size of net462 TimeZoneNames.dll
A NativeAOT ConsoleApp that references TimeZoneNames and calls each public API.
Some suggestions: There are +700 empty dictionaries, can we use a few shared empty instances instead? I noticed that |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for measuring. The rework in c3458d7 now generates a byte array instead of one huge initializer, because on the JIT the original approach was slower than main: about 500 ms of the first call was the JIT compiling the generated IL. The updated numbers are in the description. I haven't measured NativeAOT again.
|
|
With the new commit, the NativeAOT console app had these numbers:
Here's the code project I used to measure NativeAOT. <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishAot>true</PublishAot>
<InvariantGlobalization>false</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\src\TimeZoneNames\TimeZoneNames.csproj" />
</ItemGroup>
</Project>
using TimeZoneNames;
const string countryCode = "US";
const string languageCode = "en-US";
const string timeZoneId = "America/New_York";
var threshold = new DateTimeOffset(2020, 1, 1, 0, 0, 0, TimeSpan.Zero);
Console.WriteLine("GetTimeZoneIdsForCountry: " + TZNames.GetTimeZoneIdsForCountry(countryCode).Length);
Console.WriteLine("GetTimeZoneIdsForCountry with threshold: " + TZNames.GetTimeZoneIdsForCountry(countryCode, threshold).Length);
Console.WriteLine("GetTimeZonesForCountry: " + TZNames.GetTimeZonesForCountry(countryCode, languageCode).Count);
Console.WriteLine("GetTimeZonesForCountry with threshold: " + TZNames.GetTimeZonesForCountry(countryCode, languageCode, threshold).Count);
Console.WriteLine("GetFixedTimeZoneIds: " + TZNames.GetFixedTimeZoneIds().Count);
Console.WriteLine("GetFixedTimeZoneNames: " + TZNames.GetFixedTimeZoneNames(languageCode).Count);
Console.WriteLine("GetFixedTimeZoneAbbreviations: " + TZNames.GetFixedTimeZoneAbbreviations().Count);
Console.WriteLine("GetNamesForTimeZone: " + TZNames.GetNamesForTimeZone(timeZoneId, languageCode).Generic);
Console.WriteLine("GetCountryNames: " + TZNames.GetCountryNames(languageCode).Count);
Console.WriteLine("GetDisplayNameForTimeZone: " + TZNames.GetDisplayNameForTimeZone(timeZoneId, languageCode));
Console.WriteLine("GetDisplayNames: " + TZNames.GetDisplayNames(languageCode).Count);
Console.WriteLine("GetDisplayNames with IANA Zone IDs: " + TZNames.GetDisplayNames(languageCode, useIanaZoneIds: true).Count);
Console.WriteLine("GetLanguageCodes: " + TZNames.GetLanguageCodes().Count);
Console.WriteLine("GetLanguageCodes forDisplayNames false: " + TZNames.GetLanguageCodes(forDisplayNames: false).Count);
Console.WriteLine("GetLanguageCodes forDisplayNames true: " + TZNames.GetLanguageCodes(forDisplayNames: true).Count);
// Exercise obsolete APIs too so the NativeAOT smoke test covers the entire public API.
#pragma warning disable CS0618
Console.WriteLine("GetFixedTimeZoneAbbreviations: " + TZNames.GetFixedTimeZoneAbbreviations(languageCode).Count);
Console.WriteLine("GetAbbreviationsForTimeZone: " + TZNames.GetAbbreviationsForTimeZone(timeZoneId, languageCode).Generic);
#pragma warning restore CS0618 |
Replaces the gzipped JSON embedded resource with a source generator that encodes
data.jsoninto a byte array, whichTimeZoneData.Load()decodes into the same dictionaries. The first call intoTZNamesno longer decompresses and parses 10 MB of JSON.netstandard2.0,netstandard2.1andnet462.data.jsonis committed uncompressed because additional files reach a generator as text. The data itself is unchanged: it is the olddata.json.gzdecompressed. The DataBuilder now writesdata.json.ThresholdUtcis now alwaysDateTimeKind.Utc. TheDateTime.MaxValuethresholds used to load asUnspecified; the comparison ignores the kind, so results are unchanged.net10.0to the library and tests (net8.0andnet9.0to tests), and movesglobal.jsonand the DataBuilder to the .NET 10 SDK.Measurements
First
TZNames.GetDisplayNames("en-US")in a fresh .NET 9 process on Windows, Release, median of 15 runs.TimeZoneNames.dll(net9.0)NativeAOT is not measured.
Can_Get_DisplayNames_For_OS_Culturefails on my machine both before and after this change, so it is unrelated.🤖 Generated with Claude Code