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

🗑️ Prevent allocations on HasFlag checks #79

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

heytherewill
Copy link
Contributor

.HasFlag boxes the enum value. When doing that in a Draw method is allocates a bunch. I took this implementation of HasFlag which doesn't and used it where it made sense (AKA in methods that run every frame).

@isadorasophia
Copy link
Owner

isadorasophia commented May 13, 2024

That's really interesting! Do you know if that's still the case? E.g. I saw some issues like this one in the CLR and this one as of 2023. How Avalonia handled this also helped me understand it a bit more. I noticed that the IL still does the boxing at this code, I wonder if there's any JIT implementation they have done to avoid that? There's this [Intrinsic] attribute that supposedly does that.

If you can run a short benchmark/test on a console app confirming that memory does get allocated in release bits, that would also answer this! I just want to make sure that is still the case as of the latest .NET 8.

edit: It seems that, as of .NET 8, this doesn't kick in debug builds or when the method is so long that they stop being optimized.

@@ -0,0 +1,26 @@
using System.Runtime.CompilerServices;

namespace Murder.Core.Extensions;
Copy link
Owner

Choose a reason for hiding this comment

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

nit: probably should go under Utilities/ (we have a lot of extensions there haha)

/// where a `HasFlag` check needs to happen every frame.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool NonAllocatingHasFlag<TEnum>(this TEnum lhs, TEnum rhs) where TEnum : unmanaged, Enum
Copy link
Owner

Choose a reason for hiding this comment

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

I would add a big comment here specifying when this would be useful (re: debug builds or super long methods). I don't think any of the methods would currently fall into that? But I'm still okay that they call that, since I don't know for sure what "super long" means.

@heytherewill
Copy link
Contributor Author

Do you know if that's still the case?

I was getting a bunch of SOH allocations before this patch and they cease to be once I apply it, so it's definitely Still The Case. It might be an issue in Debug only, I haven't tested it in Release mode. The question is whether or not you want this to be a fix for Debug mode only or not. In case you don't you can just ignore this PR, methinks, since it does make things more confusing for an allocation gain that is not visible for the end user

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

Successfully merging this pull request may close these issues.

None yet

2 participants