Skip to content

Convert no longer necessary lambda expressions to method groups#6726

Merged
smoogipoo merged 1 commit intoppy:masterfrom
Joehuu:lambda-to-method-group
Apr 17, 2026
Merged

Convert no longer necessary lambda expressions to method groups#6726
smoogipoo merged 1 commit intoppy:masterfrom
Joehuu:lambda-to-method-group

Conversation

@Joehuu
Copy link
Copy Markdown
Member

@Joehuu Joehuu commented Mar 30, 2026

Noticed in passing. Mentioned Issues are closed, but I haven't tested performance.

@bdach
Copy link
Copy Markdown
Collaborator

bdach commented Mar 30, 2026

but I haven't tested performance

Please benchmark. KeyBindingContainer is a hot path and must keep allocs low. See #5796.

99% of the work in this PR is verifying that the dotnet issue mentioned in comments is fixed, not applying the obvious change. I'm kind of at the point where I'm no longer willing to suck it up and just test it myself.

@Joehuu
Copy link
Copy Markdown
Member Author

Joehuu commented Mar 30, 2026

Just ran what was in dotnet/runtime#33747, and it seems fixed:

Method Mean Error StdDev Allocated
ByMethodGroup 452.7 ns 4.44 ns 4.16 ns -
ByDelegate 457.6 ns 7.48 ns 7.35 ns -

@bdach
Copy link
Copy Markdown
Collaborator

bdach commented Mar 30, 2026

Please benchmark directly via our direct usage site, not via that reproducer. I'm not trying to be unreasonable, compilers are weird and sometimes they fail to optimise if an optimisation site is too indirect to be recognisable for the optimisation.

@Joehuu
Copy link
Copy Markdown
Member Author

Joehuu commented Mar 31, 2026

During .NET 6 times to compare (checked out 2c9e7a6, and reverted that commit):

Method Mean Error StdDev Gen0 Allocated
ByDelegate 1.763 ms 0.0058 ms 0.0051 ms 3007.8125 6 MB
ByMethodGroup 1.756 ms 0.0053 ms 0.0044 ms 3039.0625 6.06 MB

master:

Method Mean Error StdDev Gen0 Gen1 Allocated
ByDelegate 1.397 ms 0.0273 ms 0.0268 ms 1009.7656 13.6719 6.05 MB
ByMethodGroup 1.442 ms 0.0287 ms 0.0402 ms 1009.7656 13.6719 6.05 MB

Manually renamed to ByMethodGroup on the table with the method group change for display purposes.

A janky benchmark with unrealistic input order, doesn't hit the line if ctrl is first then f1 (adding [Test] attribute and debugging test seems to breakpoint at the line I'm benchmarking):

using BenchmarkDotNet.Attributes;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Framework.Input.States;
using osuTK.Input;

namespace osu.Framework.Benchmarks
{
    [MemoryDiagnoser]
    public partial class MethodGroupBenchmarks
    {
        [Benchmark]
        public void ByDelegate()
        {
            // use FrameworkActionContainer as it has DefaultKeyBindings
            var keyBindingContainer = new TestFrameworkActionContainer();

            for (int i = 0; i < 1000; i++)
            {
                keyBindingContainer.TriggerEvent(new KeyDownEvent(new InputState(), Key.F1));
                keyBindingContainer.TriggerEvent(new KeyDownEvent(new InputState(), Key.ControlLeft));
                keyBindingContainer.TriggerEvent(new KeyUpEvent(new InputState(), Key.F1));
                keyBindingContainer.TriggerEvent(new KeyUpEvent(new InputState(), Key.ControlLeft));
            }
        }

        private partial class TestFrameworkActionContainer : FrameworkActionContainer
        {
            public TestFrameworkActionContainer()
            {
                ReloadMappings();
            }
        }
    }
}

This is my first time benchmarking something, so sorry if this isn't the proper way.

@smoogipoo smoogipoo force-pushed the lambda-to-method-group branch from d52b2da to 633d502 Compare April 17, 2026 06:35
@smoogipoo smoogipoo merged commit 3de9c7c into ppy:master Apr 17, 2026
14 checks passed
@Joehuu Joehuu deleted the lambda-to-method-group branch April 17, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants