0

Keeping in mind this similar question does C#/Roslyn omit multiplication by 1 in cases where a variable is hard coded to 1? The similar question's answers suggest Roslyn would convert var x = 5 * 1 to var x = 5at compile time, but I wonder if this holds true for a more complex example.

Example:

var baseAmount = 25.10M;
var multiplier = 1;
var total = baseAmount * multiplier; // does this become just "baseAmount"?

Ultimately I am trying to determine if adding * 1 or an equivalent will result in performance impacts at scale (code hit millions of times). Being explicit and verbose with the * 1 multiplication in this case would result in more readable, "self-commenting" code for people new to the codebase.

jspinella
  • 2,013
  • 3
  • 25
  • 39
  • 2
    Relevant: https://ericlippert.com/2012/12/17/performance-rant/ – DavidG Sep 09 '19 at 14:04
  • 1
    Since `baseAmount` is a decimal, the multiplication will still be done. If it was an int, it might potentially be omitted. However, as hinted at in my previous comment, it's almost certainly not relevant. "Millions" of times is not going to be noticable. – DavidG Sep 09 '19 at 14:11
  • Did you try to benchmark it? – dymanoid Sep 09 '19 at 14:17
  • Absolutely, but I tend to get more info from more experienced devs here (e.g. what Roslyn does depends on whether baseAmount is a decimal (or double I assume) or a mere int). I probably would have missed that. – jspinella Sep 09 '19 at 14:49

1 Answers1

1

Looking at the disassembly of the following code:

public int test()
{
    int baseAmount = 25;
    var multiplier = 1;
    var total = baseAmount * multiplier;
    return total;
}

you can see that the imul is still there:

assembly code

Replacing multiplier by the constant 1 removes the imul:

assembly code

Changing the type of baseAmount from int to Decimal creates assembly code that is a bit more complex. With multiplier variable:

assembly code

Without multiplier:

assembly code

Looking at the assembly code, it seems that in both cases the multiply subroutine (next to the yellow arrow) is being called. So the compiler will not optimize the constant 1 in this case.

Elias N
  • 1,430
  • 11
  • 19
  • So if I understand correctly, variables hard coded to 1 are NOT recognized as "1" and therefore omitted by the compiler, e.g. baseAmount * multiplier is evaluated as such at runtime, whereas baseAmount * 1 would become just baseAmount at runtime? If this is the case, could you edit your answer with this info? – jspinella Sep 09 '19 at 14:32
  • 1
    @Elias And now try this with `decimal baseAmount = 25M;` to see why your answer is incorrect/incomplete. – DavidG Sep 09 '19 at 14:38
  • 1
    jspinella Yes that is correct. I have updated my answer with the info. @DavidG As you have mentioned, when baseAmount is a decimal, the compiler does not optimize away the constant. – Elias N Sep 09 '19 at 16:07