Looping performance with conditional C# - c#

Which of these will perform better if we assume that the IF block in #1 will be executed more and less in #2
foreach()
{
if
{
block here
}
}
or
foreach()
{
if !( )
continue
}
I've structured #2 to take the if conditional less often. But, i wanted to know if this was necessary or even helpful.

In each case, the condition will be tested. If the condition is "false", then in #1, it will skip to the end of the if block (and hence move to the next foreach item), and in #2, it will execute "continue", which does essentially the same thing.
The frequency of true/false should have no impact on this.

It generates almost exactly the same IL. Even if there was a difference, it would be so minuscule you would not be able to measure a performance delta.
I would choose one by a desire for cleanliness, not performance. The 'continue' keywork, much like the 'break' statement, can often be overlooked by other developers maintaining the code. This is especially true in more verbose foreach loops with lots of code. For this reason I prefer using the nested if then do rather than if ! continue.

Both codes are equivalent.
Don't forget that the CPU will not run your C# code.
First your C# code will be compiled into IL. It is quite possible that both codes will end up producing the same IL.
Then the IL will be compiled into machine code in a CPU-specific way.
Then the CPU will run the machine code instructions out-of-order using branch prediction. It is quite possible that the 'if' costs zero cycle because of the branch prediction.

If you want to do more of a functional approach, pull the conditional completely out of the loop like this (requires Linq):
foreach(var item in MyEnumeration.Where(x=> /* conditional on x */))
{
}

Related

how to make code more readable with compiler optimizations in place?

Code is read more often then updated. Writing more readable code is better than writing powerful and geeky code when compilers can optimize for best execution.
For example see below code - this code can be compressed by combining the nested if statements, but will the compiler not optimize this code for best execution anyway while we get to maintain the readability of it?
// yeild sunRays when sky is blue.
// yeild sunRays when sky is not blue and sun is not present.
if (yieldWhenSkyIsBlue)
{
// if sky is blue and sun is present -> yeild sunRaysObjB.
if (sunObjA != null)
{
yield return sunRaysObjB;
}
else
{
// do not yield ;
}
}
else
{
// if sky is not blue and sun is not present -> yeild sunRaysObjB.
if (sunObjA == null)
{
yield return sunRaysObjB;
}
}
As opposed to something like this :
// yeild sunRays when (sky is blue) or (sun is not present and sky is blue).
// (this interpretation is a bit misleading as compared to first one?)
if(( sunObjA == null && yieldWhenSkyIsBlue ==false) || (yieldWhenSkyIsBlue && sunObjA != null) )
{
yield return sunRaysObjB;
}
Reading the first version depicts the use case better for future enhancements\updates ? The second version of the code is shorter but reading it does not make the use case very apparent or does it ? Are there other advantages of second case apart from concise code ?
update #1 : yes it returns ObjB in both cases but based on the condition it may not yield at all. so the strategy decides when to yield and when not. ( one more reason why readability is imp)
update #2 : updated to site a better example. copied the syntax from stripplingWarrior
update #3 : updated for "What do you expect to happen when the sun is out and the sky is blue".
I think the second code example is much more readable, and has the advantage of being pretty optimal anyway.
Most programmers will find this logic flow to be obvious and natural: you will return ObjB if ObjA is null, or if it's not null and howtoYieldFalg is set.
But if I had to choose between making code like this more readable and making it optimal, I'd make it readable first. Only if I discovered that it's the source of a bottleneck would I bother optimizing it. In this particular case, I can pretty much guarantee that your use of yield return will introduce way more overhead than a suboptimal evaluation of your conditionals.
Update
Take another look at your code samples: they are not logically equivalent. What do you expect to happen when the sun is out and the sky is blue? The second code sample correctly allows sun rays to shine in that case, whereas the first example does not.
The fact that it was so easy to introduce a bug in the first case which so many people failed to catch for so long should be ample evidence to show that the second approach is better. All those nested if/else statements can be tricky to keep straight, even to an experienced programmer. Simple boolean logic is a lot easier to keep straight, especially once you use variable names that give it meaning.
Update 2
Based on the further explanation, and with a little creativity, I'm going to suggest an approach that uses both comments and variable names to increase clarity:
/* Explanation: We live on a strange planet where the sun's
* rays can shine if the sky is blue while the sun is out,
* or if the sky is not blue and there is no sun. */
bool sunIsPresent = sunObjA != null;
if ((skyIsBlue && sunIsPresent) ||
(!skyIsBlue && !sunIsPresent))
{
yield return sunRaysObjB;
}
The compiler optimizes right through any way you organize your program's control flow, so you really do not have to worry about it.
The weakness of compilers though, is they only optimize based on preserving code semantics, not preserving the meaning you intend. I compiled both your examples in LLVM, and here are the control flow graphs generated:
and
I was surprised to find the two CFG's are slightly different. You will note that first is an instruction smaller, but in the second graph, there exists a path to the exit node which only passes through one comparison, whereas in the first, two comparisons are always necessary.
In fact, further tracing of possible routes yields that the first example has possible routes of 6,8,8,6 instructions long, while the second has routes of 8,10,10 respectively. In BOTH cases the average run length is 7 instructions long, but we can see that the first case has better best-time run lengths. Without more information the compiler cannot tell which is better.
tldr: Compilers do magic stuff, don't worry about it, code how you think is best.
This is probably not the popular opinion but I'd definitely not rely on the compiler to perform optimizations of this type. (It may do it, I don't know.) I don't see the second example as geeky - for me it describes more clearly that the two conditions are connected.
Typically I try to write as optimal code as possible without making it very cryptic and then let the compiler optimize that.
Though I haven't tested this particular case, I'm willing to bet that there will be no significant difference between the generated code, if any at all.
Unless you're doing it for fun or a specialized use case, I would argue human-readability is by far the more important quality of good code. The compiler is going to collapse much of your expressive code into more efficient forms, and what it misses you probably won't ever notice.
Given that, idiomatic code is easier to read even when it's less concise. Experienced readers of a language are going to recognize a common pattern more quickly than unfamiliar code that is, arguably 'more human' but breaks the familiar pattern. Looping/incrementing constructs are a good example of code that should be unsurprising. So, my approach is: Be expressive but not too clever.

Use of Goto within lexer/parser

I have a lexer/parser pair (which I cribbed off someone else years ago). I am going to be adding a couple of features and thought I would first standardise the use of while(true) containing multiple if/else if/else vs a switch which uses a goto to jump back to before the switch.
(Before the flames start, I don't normally use goto as its evil etc. etc.)
The problem with a while(true) and a nested switch is that the break only breaks out of the switch and cannot get outside the while.
I have done some searching here and seen suggestions to use a return from inside the switch. Whilst this would work in some cases, in others, there is some processing after the while but before returning. Duplicating this code in multiple places doesn't really appeal.
I could also introduce a boolean flag and use that in the while statement to decide whether to break out of the while but that also doesn't appeal as it adds noise to the code.
The current way in the parser of using if/else if/else instead of an inner switch works but I do have a preference for a switch if possible.
The lexer code in general seems to get around this by removing the while(true) and putting a label just before the switch start and using goto to continue the loop. This leaves break meaning stop the loop and, to be honest, seems the cleanest way but does involve the dreadead goto.
Going back to the while(true), I can also see a third way. Use a label after the while(true) and let the switch code use goto to get to it when the loop should end. Break would then mean exit the switch but continue the loop.
So what are the panels views on this? Is goto too abhorrent to use? Or is it OK when there is just a single label to jump to and reduces indenting and produces otherwise clear code? Should parsers/lexers get special license to use gotos?
I can provide some sample code if it would help.
Use of GOTO in disciplined ways is fine. Languages which don't allow breaks out of arbitrarily nested block structures cause this question to be raised repeatedly, since the 1970s when people beat the question of "what control flow structures should a langauge have" to death. (Note: this complaint isn't special to lexers/parsers).
You don't want the scheme with boolean; it just adds extra overhead to the loop checks and clutters the code.
I think you have this problem:
<if/while/loop head> {
<if/while/loop head> {
...
if <cond> <want to break out all blocks>
...
}
}
The proper cure with a good language is:
blocks_label:
<if/while/loop head> {
<if/while/loop head> {
...
if <cond> exit blocks_label;
...
}
}
if the exit construct exists in your language, that exits
the blocks labelled by the named label. (There's no excuse
for a modern langauge to not have this, but then, I don't
design them).
It is perfectly satisfactory to write, as a poor man's substitute:
<if/while/loop head> {
<if/while/loop head> {
...
if <cond> goto exit_these_blocks;
...
}
}
exit_these_blocks: // my language doesn't have decent block exits
On occasion you'll find a language that offers
break <exp>
where exp is usually a constant whole number, meaning, "break out of exp nested blocks". This is an astoundingly stupid idea, as some poor maintainer may later come along an insert another block somewhere in the stack, and now the code does crazy things. (In fact, this exact mistake in a telco switch took out the entire East Coast phone system about 20 years ago). If you see this construct in your langauge, use the poor man's substitute instead.
Within parsers the use of GOTO is perfectly reasonable. When you get down to a base level, the loops and conditions etc are all implemented as gotos, because that is what processors can do - "take the next instruction to be executed from here".
The only problems with gotos, and the reason they are so often demonised, is that they can be an indication of unstructured code, coming form unstructured thinking. Within modern high level languages, there is no need for gotos, because all of the facilities are available to structure code well, and well structured code implies at least some structured thinking.
So use gotos if they are needed. Don't use them just because you can't be bothered to think things through properly.

Dictionary Performance

Whats the difference between the teo snippets?
Snippet 1:
{
Dictionary<MyCLass, bool> dic;
MyFunc(out dic);
}
Snippet 2:
{
Dictionary<MyCLass, bool> dic = null;
MyFunc(out dic);
}
Is snippet 2 better in performance?
Technically speaking the second code snippet will likely execute more instructions than the first by doing a redundant null set. I'm hedging with likely here because the C# spec may allow for the flexibility of ignoring this set. I don't know off hand.
However I would seriously doubt that would ever noticeably affect performance of an application. I certainly would not code for that optimization but would instead prefer the solution which I found more understandable.
Do not worry about these when you haven't measured the performance of the application.
Things like this are very unlikely to have a huge impact, in fact, most of the time things like this will not be noticeable compared to other lines you wrote.
Measure first, them worry about performance.
I like snippet 2, it's slower but better practice to reduce errors, overall a good habit to have - to init variables explicitly. Maybe even the JIT can optimize it away at access time so you only lose a little bit of performance at compile & load time not at execution (but I haven't verified this debugger/disassembler but the JIT is quite 'smart' for a computer program so it maybe able to do it)
Compile them both and compare the IL. I imagine it would be the same. The storage for the out parameter should be initialized to zero (null, if it is a reference type) before it its passed to the called method.

How much does bytecode size impact JIT / Inlining / Performance?

I've been poking around mscorlib to see how the generic collection optimized their enumerators and I stumbled on this:
// in List<T>.Enumerator<T>
public bool MoveNext()
{
List<T> list = this.list;
if ((this.version == list._version) && (this.index < list._size))
{
this.current = list._items[this.index];
this.index++;
return true;
}
return this.MoveNextRare();
}
The stack size is 3, and the size of the bytecode should be 80 bytes. The naming of the MoveNextRare method got me on my toes and it contains an error case as well as an empty collection case, so obviously this is breaching separation of concern.
I assume the MoveNext method is split this way to optimize stack space and help the JIT, and I'd like to do the same for some of my perf bottlenecks, but without hard data, I don't want my voodoo programming turning into cargo-cult ;)
Thanks!
Florian
If you're going to think about ways in which List<T>.Enumerator is "odd" for the sake of performance, consider this first: it's a mutable struct. Feel free to recoil with horror; I know I do.
Ultimately, I wouldn't start mimicking optimisations from the BCL without benchmarking/profiling what difference they make in your specific application. It may well be appropriate for the BCL but not for you; don't forget that the BCL goes through the whole NGEN-alike service on install. The only way to find out what's appropriate for your application is to measure it.
You say you want to try the same kind of thing for your performance bottlenecks: that suggests you already know the bottlenecks, which suggests you've got some sort of measurement in place. So, try this optimisation and measure it, then see whether the gain in performance is worth the pain of readability/maintenance which goes with it.
There's nothing cargo-culty about trying something and measuring it, then making decisions based on that evidence.
Separating it into two functions has some advantages:
If the method were to be inlined, only the fast path would be inlined and the error handling would still be a function call. This prevents inlining from costing too much extra space. But 80 bytes of IL is probably still above the threshold for inlining (it was once documented as 32 bytes, don't know if it's changed since .NET 2.0).
Even if it isn't inlined, the function will be smaller and fit within the CPU's instruction cache more easily, and since the slow path is separate, it won't have to be fetched into cache every time the fast path is.
It may help the CPU branch predictor optimize for the more common path (returning true).
I think that MoveNextRare is always going to return false, but by structuring it like this it becomes a tail call, and if it's private and can only be called from here then the JIT could theoretically build a custom calling convention between these two methods that consists of just a jmp instruction with no prologue and no duplication of epilogue.

Nested or not nested if-blocks?

I was wondering if there is a performance difference when using ifs in C#, and they are nested or not. Here's an example:
if(hello == true) {
if(index == 34) {
DoSomething();
}
}
Is this faster or slower than this:
if(hello == true && index == 34) {
DoSomething();
}
Any ideas?
Probably the compiler is smart enough to generate the same, or very similar code, for both versions. Unless performance is really a critical factor for your application, I would automatically choose the second version, for the sake of code readability.
Even better would be
if(SomethingShouldBeDone()) {
DoSomething();
}
...meanwhile in another part of the city...
private bool SomethingShouldBeDone()
{
return this.hello == true && this.index == 34;
}
In 99% of real-life situations this will have little or no performance impact, and provided you name things meaningfully it will be much easier to read, understand and (therefore) maintain.
Use whichever is most readable and still correct (sometimes juggling around boolean expressions will get you different behavior - especially if short-circuiting is involved). The execution time will be the same (or too close to matter).
Just for the record, sometimes I find nesting to be more readable (if the expression turns out to be too long or to have too many components) and sometimes I find it to be less readable (as in your short example).
Any modern compiler, and by that I mean anything built in the past 20 years, will compile these to the same code.
As to which you should use then it depends whichever is more readable and logical in the context of the project). Generally I would go for the second myself, but that would vary.
A strong point worth consideration though arises from maintenance. One of the more common bugs I have hunted down is a dangling if/else in the middle of a block of nested ifs. This arises if you have a complex series of if else conditions which has been amended by different programmers over a period - often several years. For example using pseudo-code for a simple case:
IF condition_a
IF condition_b
Do something
ELSE
Do something
END IF
ELSE
IF condition_b
Do something
END IF
END IF
you'll notice for the combination !condition_a && !condition_b the code will fall through the conditions doing nothing. This is quite easy to spot for just the pair of conditions, but can get very easy to miss very quickly once you have 3, 4 or more if/else conditions to check. What commonly happens is the nested structure is correct when first coded, but becomes incorrect (in terms of the business outputs) at some later point because the maintenance programmers will not understand or allow for the full range of options.
It's therefore generally more robust, over time, to code using combined conditions in the if structure adopting the flatest feasible structure and keep nesting to a minimum, hence with your example as there's no logical reason not to combine the two conditions into a single statement then you should do so
I can't see that there will be any great performance difference with either, but I do think that option two is MUCH more readable.
I don't believe there is any performance difference you might be experiencing between the two implementation..
Anyway, I go for for the latter implementation because it is more readable.
Depends on the compiler. The difference will be more apparent when you have code after the close of the nested if, but before the close of the outer.
I've wondered about this often myself. However, it seems there really is no difference (or not much to speak of) between the options. Readability-wise, the second option is more readable and so I usually choose that one unless I anticipate having to code specifically for each condition for some reason.

Categories