Skip to content

Conversation

xtqqczze
Copy link
Contributor

@xtqqczze xtqqczze commented Jul 29, 2025

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
Copy link
Member

jkotas commented Jul 29, 2025

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
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
Copy link
Member

jkotas commented Jul 31, 2025

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

@xtqqczze
Copy link
Contributor Author

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

@EgorBo Could you help verify this?

@EgorBo
Copy link
Member

EgorBo commented Jul 31, 2025

@MihuBot

@xtqqczze
Copy link
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
Member

Windows target

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

@jkotas
Copy link
Member

jkotas commented Aug 1, 2025

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.., ];.

@xtqqczze

This comment was marked as outdated.

@jkotas
Copy link
Member

jkotas commented Aug 1, 2025

@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.

@xtqqczze

This comment has been minimized.

@xtqqczze
Copy link
Contributor Author

xtqqczze commented Aug 2, 2025

@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
Copy link
Member

jkotas commented Aug 2, 2025

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

Copy link
Member

@jkotas jkotas left a comment

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