-
Notifications
You must be signed in to change notification settings - Fork 57
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
base: main
Are you sure you want to change the base?
Conversation
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 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; |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
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 |
.HasFlag
boxes the enum value. When doing that in a Draw method is allocates a bunch. I took this implementation ofHasFlag
which doesn't and used it where it made sense (AKA in methods that run every frame).