Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider wrapping throw in call to encourage JITter #320

Open
mtmk opened this issue Jan 10, 2024 · 3 comments
Open

Consider wrapping throw in call to encourage JITter #320

mtmk opened this issue Jan 10, 2024 · 3 comments
Labels

Comments

@mtmk
Copy link
Collaborator

mtmk commented Jan 10, 2024

NIT/Future: Consider wrapping throw in call to encourage JITter.

Originally posted by @to11mtm in #303 (comment)

@to11mtm
Copy link
Contributor

to11mtm commented Jan 11, 2024

So, to elaborate here... Apologies, priorities abound...

In general we should, when throwing in potentially hot methods, prefer to call a ThrowHelper() instead of throwing.

As a very good example

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int GetInt32(ReadOnlySpan<byte> span)
{
if (!Utf8Parser.TryParse(span, out int value, out var consumed))
{
throw new Exception(); // throw...
}
return value;
}

the fact we are throwing actually causes a number of optimizations to not happen and can also impact inline ability.

An example refactoring would be:

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private static int GetInt32(ReadOnlySpan<byte> span)
    {
        if (!Utf8Parser.TryParse(span, out int value, out var consumed))
        {
            ThrowOnUtf8ParseFail();
        }

        return value;
    }
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void ThrowOnUtf8ParseFail()
    {
        throw new Exception();
    }

@to11mtm
Copy link
Contributor

to11mtm commented Jan 11, 2024

Further Docs and explanation of potential value for perf: (FWIW these are from CommunityToolkit's Diagnostic analyzer docs, so we could, if we wanted, add as an analyzer to help identify across projects[0])

https://learn.microsoft.com/en-us/dotnet/communitytoolkit/diagnostics/throwhelper#technical-details

We probably should have some form of:

internal static class ThrowHelpers
{
    //example, add others to taste
    [MethodImpl(MethodImplOptions.NoInlining)] //may be too paranoid
    public void ThrowNatsException(string message)
    {
        throw new NatsException(message);
    }
}

And use that when throwing on hot paths/etc.

[0] - I think that analyzer will only really work if we take CommunityToolKit as a dependency and we want to stay lean, so probably not for now.

@mtmk
Copy link
Collaborator Author

mtmk commented Jan 12, 2024

Makes sense. Also runtime libs are always using this. We could start with read/write loops maybe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants