Skip to content

Refactor known folder GUIDs to use static properties#118165

Merged
jkotas merged 6 commits into
dotnet:mainfrom
xtqqczze:const-Guid-string
Aug 3, 2025
Merged

Refactor known folder GUIDs to use static properties#118165
jkotas merged 6 commits into
dotnet:mainfrom
xtqqczze:const-Guid-string

Conversation

@xtqqczze

@xtqqczze xtqqczze commented Jul 29, 2025

Copy link
Copy Markdown
Contributor

The following regular expression was used:

internal const string ([a-z0-9]+) = "\{([a-z0-9]{8})-([a-z0-9]{4})-([a-z0-9]{4})-([a-z0-9]{2})([a-z0-9]{2})-([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})\}";

internal static Guid $1 => new(0x$2, 0x$3, 0x$4, 0x$5, 0x$6, 0x$7, 0x$8, 0x$9, 0x$10, 0x$11, 0x$12);

@github-actions github-actions Bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Jul 29, 2025
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Jul 29, 2025
…ants

internal const string ([a-z0-9]+) = "\{([a-z0-9]{8})-([a-z0-9]{4})-([a-z0-9]{4})-([a-z0-9]{2})([a-z0-9]{2})-([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})\}";

internal static Guid $1 => new(0x$2, 0x$3, 0x$4, 0x$5, 0x$6, 0x$7, 0x$8, 0x$9, 0x$10, 0x$11, 0x$12);
@xtqqczze xtqqczze force-pushed the const-Guid-string branch from 2a9ad80 to 77f5d77 Compare July 29, 2025 15:00
@jkotas jkotas added area-System.Runtime and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Jul 29, 2025
@jkotas

jkotas commented Jul 29, 2025

Copy link
Copy Markdown
Member

Is this expected to be a perf improvement? Do you have any numbers (for the public Environment APIs) to demonstrate that this is better?

@xtqqczze

This comment has been minimized.

@xtqqczze

Copy link
Copy Markdown
Contributor Author

Is this expected to be a perf improvement? Do you have any numbers (for the public Environment APIs) to demonstrate that this is better?

This was expected to be a performance improvement as it avoids the overhead of initialising a Guid from a string, see https://csharp.godbolt.org/z/vxKqKjT4r

However System.Tests.Perf_Environment.GetFolderPath benchmark fails to show significant improvements.

@jkotas

jkotas commented Jul 31, 2025

Copy link
Copy Markdown
Member

How about code size metrics? Is this a binary size improvement, e.g. for NAOT?

@xtqqczze

Copy link
Copy Markdown
Contributor Author

How about code size metrics? Is this a binary size improvement, e.g. for NAOT?

@EgorBo Could you help verify this?

@EgorBo

EgorBo commented Jul 31, 2025

Copy link
Copy Markdown
Member

@MihuBot

@xtqqczze

Copy link
Copy Markdown
Contributor Author

MihuBot

@MihaZupan These changes are specific to Windows target, is this an option with MihuBot?

@xtqqczze

This comment was marked as outdated.

@MihaZupan

Copy link
Copy Markdown
Member

Windows target

No, hasn't been wired through for the JIT diffs

@jkotas

jkotas commented Aug 1, 2025

Copy link
Copy Markdown
Member

1kb is not that much and it is 4kB regression for non-NAOT (16,031,744 -> 16,035,840 - there can be some rounding error in this).

Have you tried to actually step through the code to see where to make this better? I see:

  • The public entrypoint calls Enum.IsDefined (potentially two times) that is fairly inefficient. We can rid of the GetFolderPath/GetFolderPathCore split of the worker method and Enum.IsDefined calls on the main path.
    • For SpecialFolderOption, we can check the 3 valid values.
    • For SpecialFolder, we can throw in the default case of the switch statement (avoid Enum.IsDefined completely), or call Enum.IsDefined in the default case of the switch statement only (pay for Enum.IsDefined at runtime in rare cases only)
  • The Guid properties are not inlined on Windows. There is a lot of extra code to pass the return buffers, etc. If we care about making this efficient, would it be better to store these as byte arrays? Like, internal static ReadOnlySpan<byte> AdminTools => [0x.., 0x.., ];.

Comment thread src/libraries/Common/src/Interop/Windows/Shell32/Interop.SHGetKnownFolderPath.cs Outdated
@xtqqczze

This comment was marked as outdated.

@jkotas

jkotas commented Aug 1, 2025

Copy link
Copy Markdown
Member

@EgorBot --filter "System.Tests.Perf_Environment.GetFolderPath"

I do not expect that this ReadOnlySpan change is going improve throughput over the previous version. It is code size improvement.

You may see some throughput improvement if you get rid of Enum.IsDefined calls.

Comment thread src/libraries/System.Private.CoreLib/src/System/Environment.cs Outdated
Comment thread src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs Outdated
Comment thread src/libraries/System.Private.CoreLib/src/System/Environment.cs
@xtqqczze

This comment has been minimized.

@xtqqczze

xtqqczze commented Aug 2, 2025

Copy link
Copy Markdown
Contributor Author

@EgorBo There is no correctness issue for big-endian platforms, since we call Guid(ReadOnlySpan).

Using Unsafe.As<byte, Guid>(ref MemoryMarshal.GetReference(folderId)) was considered and rejected.

@jkotas

jkotas commented Aug 2, 2025

Copy link
Copy Markdown
Member

4kb-5kB improvement for NAOT MichalStrehovsky/rt-sz#159 (comment)

@jkotas jkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks

@jkotas jkotas merged commit 3f25a27 into dotnet:main Aug 3, 2025
137 of 143 checks passed
@xtqqczze xtqqczze deleted the const-Guid-string branch August 3, 2025 12:23
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 3, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Runtime community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants