33

I've been trying to optimize my code to make it a little more concise and readable and was hoping I wasn't causing poorer performance from doing it. I think my changes might have slowed down my application, but it might just be in my head. Is there any performance difference between:

Command.Parameters["@EMAIL"].Value = email ?? String.Empty;

and

Command.Parameters["@EMAIL"].Value = (email == null) ? String.Empty: email;

and

if (email == null)
{
    Command.Parameters["@EMAIL"].Value = String.Empty
}
else
{
    Command.Parameters["@EMAIL"].Value = email
}

My preference for readability would be the null coalescing operator, I just didn't want it to affect performance.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Jon
  • 5,956
  • 10
  • 39
  • 40

7 Answers7

72

You are trying to micro-optimize here, and that's generally a big no-no. Unless you have performance analytics which are showing you that this is an issue, it's not even worth changing.

For general use, the correct answer is whatever is easier to maintain.

For the hell of it though, the IL for the null coalescing operator is:

L_0001: ldsfld string ConsoleApplication2.Program::myString
L_0006: dup 
L_0007: brtrue.s L_000f
L_0009: pop 
L_000a: ldsfld string [mscorlib]System.String::Empty
L_000f: stloc.0 

And the IL for the switch is:

L_0001: ldsfld string ConsoleApplication2.Program::myString
L_0006: brfalse.s L_000f
L_0008: ldsfld string ConsoleApplication2.Program::myString
L_000d: br.s L_0014
L_000f: ldsfld string [mscorlib]System.String::Empty
L_0014: stloc.0 

For the null coalescing operator, if the value is null, then six of the statements are executed, whereas with the switch, four operations are performed.

In the case of a not null value, the null coalescing operator performs four operations versus five operations.

Of course, this assumes that all IL operations take the same amount of time, which is not the case.

Anyways, hopefully you can see how optimizing on this micro scale can start to diminish returns pretty quickly.

That being said, in the end, for most cases whatever is the easiest to read and maintain in this case is the right answer.

If you find you are doing this on a scale where it proves to be inefficient (and those cases are few and far between), then you should measure to see which has a better performance and then make that specific optimization.

Servy
  • 202,030
  • 26
  • 332
  • 449
casperOne
  • 73,706
  • 19
  • 184
  • 253
69

IMHO, optimize for readability and understanding - any run-time performance gains will likely be minimal compared to the time it takes you in the real-world when you come back to this code in a couple months and try to understand what the heck you were doing in the first place.

PhilChuang
  • 2,556
  • 1
  • 23
  • 29
  • 13
    Of course, bear in mind that a lot of programmers can read ? : statements just as fast as regular if statements. In some cases they are even more clear than using if / else statements without braces. – NotMe Feb 13 '09 at 19:49
  • 1
    I agree. Many posts here are performance questions, asking about minor tweaks (is ++ faster than +=1?) that don't really matter. Speed comes from algorithmic complexity: reducing massive mem-copies, searching containers quickly, hashing appropriately. Minor tweaks have no performance impact. – abelenky Feb 13 '09 at 19:55
  • 10
    -1: While chublogga's points are all true and valid and well phrased, they don't answer the original question. The OP is a grown-up who can make his own architecture/readability choices, and casperOne's answer is really a more interesting and direct answer to the specific question of performance. – nezroy Feb 13 '09 at 20:33
  • 1
    I didn't answer the original question because it was the wrong question to begin with. – PhilChuang Feb 14 '09 at 05:30
  • 1
    Isn't it safe to assume that if a human can see the obvious, a compiler would be smart enough to see that and beyond? – Ustaman Sangat Feb 10 '12 at 03:12
  • I personally read coalescing much faster and easier, but that's just me. Same would be true for ternary operators too – chris c Mar 07 '22 at 05:26
18

I think my changes might have slowed down my application, but it might just be in my head.

Unless you are actually measuring performance, it's all in your head and idle speculation.

(Not to pick on you in particular, but it is so disappointing to see question after question about performance micro-optimizations (as well as many of the answers) that do not contain the word "measure".)

Brian
  • 117,631
  • 17
  • 236
  • 300
7

I suspect there won't be any performance difference.

Next to that, I wonder why you would have any concerns of favoring one statement over the other in this case ? I mean: the performance impact (if there should be any), would be minimal. IMHO, this would be a kind of micro-optimization, and it shouldn't be worth the effort.
I would choose the statement that is most readable, most clear, and not worry about performance since it would be of minimal influence (in this case).

Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
  • 1
    The way it was originally written was a bunch of if statements and when I changed it, it seemed like the program took a little performance hit. Maybe it was an isolated incident but it sparked my interest more than anything. – Jon Feb 13 '09 at 19:19
7

Almost no significant performance difference in this case.

When the performance difference is negligible, it is all about readable code.

Chris Ballance
  • 33,810
  • 26
  • 104
  • 151
  • 1
    I'd refine that to say "In cases where there is no significant performance difference, it is all about readable code." Sometimes, there is a performance difference, and sometimes that difference is significant, in which case, code readability may take a back seat. – phoog Nov 25 '10 at 12:41
  • 1
    How is that any different from what I said? – Chris Ballance Jul 26 '13 at 18:36
  • @chris-ballance The difference is obviously in where one puts the emphasis. – Johan Boulé May 08 '15 at 11:14
2

For discussion sake... if/then/else runs just as fast as the ?: ternary operation as fast as a single level switch/case statement.

Here are some performance benchmarks with the C# code.

It's only when you start getting 2-3 levels deep in case statements that performance starts to be severely impacted. That is, something like this ridiculous example:

switch (x % 3)
    {
        case 0:
            switch (y % 3)
            {
                case 0: total += 3;
                    break;
                case 1: total += 2;
                    break;
                case 2: total += 1;
                    break;
                default: total += 0;
                    break;
            }
            break;
        case 1:
            switch (y % 3)
            {
                case 0: total += 3;
                    break;
                case 1: total += 2;
                    break;
                case 2: total += 1;
                    break;
                default: total += 0;
                    break;
            }
            break;
    case 2:
            switch (y % 3)
            {
                case 0: total += 3;
                    break;
                case 1: total += 2;
                    break;
                case 2: total += 1;
                    break;
                default: total += 0;
                    break;
            }
            break;
    default:
        switch (y % 3)
        {
            case 0: total += 3;
                break;
            case 1: total += 2;
                break;
            case 2: total += 1;
                break;
            default: total += 0;
                break;
        }
        break;
    }
1

Its a Question of whether machine level code is efficient or Human Readable Code. As we making it more Readable to us, it makes machine to do Complex interpret the code and vice versa...