DEV Community

loading...

Who am I? Me, the name of the currently executing method in C# (Part 2)

Bruce Axtens
Programmed Canon Canola calculators in 1977. Assorted platforms and languages ever since. Assisting with HOPL.info. I am NOT looking for work -- I've got more than enough to do.
Updated on ・2 min read

It seems that thinking about Me all the time is problematic outside of personal relationships as well as within them. In part 1 I discussed my JavaScript and C# implementation of Me.

A couple of exceptionally helpful people have pointed out that my approach is rather expensive in terms of run-time speed. Being curious (and desiring to be distracted), I cooked up a quick benchmark of the two approaches (mine and the one suggested by Matt Eland).

The benchmarking code is derived from a Stackoverflow solution provided by one Alex Erygin.

First the benchmarking code:

using System;
using System.Diagnostics;

namespace dotnets
{
    public class Benchmark : IDisposable
    {
        private readonly Stopwatch timer = new Stopwatch();
        private readonly string benchmarkName;

        public Benchmark(string benchmarkName)
        {
            this.benchmarkName = benchmarkName;
            timer.Start();
        }

        public void Dispose()
        {
            timer.Stop();
            Console.WriteLine($"{benchmarkName} {timer.Elapsed}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Then the Main

using System;
using System.Diagnostics;

namespace dotnets
{
    class Program
    {
        private static string Me => new StackTrace().GetFrame(1).GetMethod().Name;

        static void Main(string[] args)
        {
            using (var bench = new Benchmark("Using Me"))  {
                for(var i = 0; i < 1000; i++) foo1();
            }
            using (var bench = new Benchmark("Using nameof"))  {
                for(var i = 0; i < 1000; i++) foo2();
            }
        }

        static string foo1()
        {
            var me = Me;
            return me;
        }
        static string foo2()
        {
            var me = nameof(foo2);
            return me;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Then a copy of a Debug run

>dotnet run
Using Me 00:00:00.0122772
Using nameof 00:00:00.0001258
Enter fullscreen mode Exit fullscreen mode

and a Release run

>dotnet run -c Release
Using Me 00:00:00.0164321
Using nameof 00:00:00.0000010
Enter fullscreen mode Exit fullscreen mode

nameof being resolved at compile-time is clearly the winner. So if run-time speed is an issue for you, use nameof.

Discussion (3)

Collapse
katnel20 profile image
Katie Nelson

Thanks Bruce. I learn something new everyday!
As a suggestion for a future topic: the Dispose pattern used in .NET (I'm confused on whether it takes a bool or not).

Collapse
bugmagnet profile image
Bruce Axtens Author • Edited

I'm intrigued by Erygin's Dispose pattern too. What he is doing is following C#'s Destructor pattern rather than its Finalizer pattern. See Implementing IDisposable and the Dispose Pattern Properly.

It would be interesting to discover whether a Finalizer would work in the same way for a using block as is done in the Benchmark object.

As for the Dispose taking a second parameter, that is mentioned in the Microsoft documentation Implementing a Dispose method which says

The Dispose(Boolean) overload

In the second overload, the disposing parameter is a Boolean that indicates whether the method call comes from a Dispose method (its value is true) or from a finalizer (its value is false).

The Destructor pattern examples I've seen so far don't use this overload. However, the CodeProject article goes into a lot of detail and does discuss the second form thoroughly.

Collapse
katnel20 profile image
Katie Nelson

I looked at that CodeProject article as you suggested. It's very detailed and will take me some time to fully digest. The Microsoft doc seems to be a little more precise. I'm just surprised that to use Dispose correctly, you have to keep track it's usage with your own flag. Seems like old school programming. Whenever I use flags in my stuff, our coding advisor always makes a face!

Thanks again for the information. I'll be sure to use it.