Click here to Skip to main content
15,892,161 members
Articles / Programming Languages / C#

Performance: Enum ToString or GetName

Rate me:
Please Sign up or sign in to vote.
4.50/5 (8 votes)
30 Dec 2016CPOL2 min read 19.5K   10   6
Performance: Enum ToString or GetName

Image 1

Usually I am too lazy to bother using anything else than the ordinary ToString when working with enums, but I always have that filthy feeling that I am cheating.

If there is a dedicated method in the framework to do something, there probably is a reason for it. And knowing that the Enum class contains a GetName method to get the string representation of an enum value made me want to know if there is a performance difference between the two.

First, the tested Enum.GetName method, for the sake of argument is wrapped up as an Extension for easier and cleaner usage.

C#
public static class Extension
{
    public static string GetEnumName<T>(this T t) where T : struct, IConvertible
    {
        return Enum.GetName(typeof (T), t);
    }
}

Back to extensions list.

The test rigg

The test rigg is basically the same that I used in Performance of different lock methods in .NET. Uses RunningAverage to calculate the average without storing each individual number.

Just cleaned up and simplified for this scenario:

Data

C#
private enum SmallEnum
{
    Small,
    Larger
}
private enum LargerEnum
{
    a, b, c, d, e, f, g, h,
    aaaaa, bbbbb, ccccc, ddddd,
    xxxxx, yyyyy, zzzzz,
    VeryLongNameThisIs,
    OtherName, Test, oooo, olf,
    eowind, eeeee, ss, qqqqq,
    mu, miu, bach, escher,
    godel, code, number, last
}

I decided to test 2 different enums with different number of elements to see if that has any impact. The small has 2 elements and the larger has 32.

Code

C#
private void ExecuteTestSmall(int iterations)
{
    var type = "small";
    string s = string.Empty;
    try
    {
        var testData = GenerateTestDataSmall();
        var toStringTimings = new RunningAverage();
        var getNameTimings = new RunningAverage();
        for (int i = 0; i < iterations; i++)
        {
            for (int dataIndex = 0; dataIndex < testData.Count; dataIndex++)
            {
                var item = testData[dataIndex];
                toStringTimings.Add(TimeAction(() =>
                {
                    s = item.ToString();
                }));
                if (!string.IsNullOrEmpty(s))
                    s = string.Empty;
                getNameTimings.Add(TimeAction(() =>
                {
                    s = item.GetEnumName();
                }));
                if (!string.IsNullOrEmpty(s))
                    s = string.Empty;
            }
        }
        Log($"{type}ToString\tDataCount\t2\tIterations:\t{iterations}\tAverage:\t{toStringTimings.Average:0.000}\tticks");
        Log($"{type}GetName\tDataCount\t2\tIterations:\t{iterations}\tAverage:\t{getNameTimings.Average:0.000}\tticks");
    }
    catch (Exception ex)
    {
        Log($"{type}Fail\tDataCount\t2\tIterations:\t{iterations}\tFailed\t{ex.Message}");
    }
}

Ok, I was lazy. I created 2 methods instead of putting the effort to reuse it. The above is for the SmallEnum. Exactly the same code for the LargerEnum tester with difference in GenerateTestDataSmall to return a List<LargerEnum> instead of List<SmallEnum>.

This was executed as follows:

C#
public void Execute()
{
 Log("--------------------------------------");
 Log("... single thread");
 ExecuteTestSmall(250000);
 ExecuteTestLarger(250000);
}

250000 times each.

Results

ToStringenum size2Iterations:250000Average:1.231ticks
GetNameenum size2Iterations:250000Average:0.662ticks
ToStringenum size32Iterations:250000Average:1.357ticks
GetNameenum size32Iterations:250000Average:0.692ticks

Conclusion

Using the dedicated Enum.GetName function to get the string representation instead of the lazy object.ToString() seems to be twice faster. But in the end, we are talking around 1 tick, so maybe not the first place to start optimizing if you have a performance issue in you application. As I wrote above, it just feels a little bit lazy to not do it the correct way. ;)

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Hope this helps someone out there. :)

Until next time: Work to Live, Don’t Live to Work

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Sweden Sweden
http://dreamstatecoding.blogspot.com

Comments and Discussions

 
QuestionNo output for 'Flag' enums. Pin
Jens Madsen, Højby2-Jan-17 21:38
Jens Madsen, Højby2-Jan-17 21:38 
QuestionC# source code Pin
tbayart2-Jan-17 5:49
professionaltbayart2-Jan-17 5:49 
AnswerRe: C# source code Pin
Gary R. Wheeler2-Jan-17 6:05
Gary R. Wheeler2-Jan-17 6:05 
QuestionFormatting issues Pin
Wendelius29-Dec-16 19:45
mentorWendelius29-Dec-16 19:45 
AnswerRe: Formatting issues Pin
Eowind30-Dec-16 6:33
Eowind30-Dec-16 6:33 
PraiseRe: Formatting issues Pin
Wendelius30-Dec-16 6:36
mentorWendelius30-Dec-16 6:36 
Looks all good now Smile | :)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.