Booleans versus memory

We discussed working on code design, and one of the problems was handling responses from invoking a logical method as follows:

bool ok = IsEverythingOK(); if(ok) { //do somehthing } 

One of my colleagues insists that we skip the extra variable ok and write

 if(IsEverythingOK()) { //do somehthing } 

Since he says that using the "bool ok" strategy is bad in memory.

Which one should we use?

+5
source share
4 answers

It all depends on whether you are doing anything with ok inside the loop.

i.e.

 bool ok = IsEverythingOK(); if(ok) { //do somehthing ok = IsEverythingOK(); } 

Assuming you do nothing with ok in the loop, you will probably find that the JIT compiler will turn:

 bool ok = IsEverythingOK(); if(ok) { //do somehthing } 

... primarily:

 if(IsEverythingOK()) { //do somehthing } 

... anyway.

+3
source

To paraphrase your question:

Is there a cost to using a local variable?

Since C # and .NET are well designed, I expect that using a local variable as you have described does not have or has a negligible cost, but let me try to support this expectation with some facts.

The following C # code

 if (IsEverythingOk()) { ... } 

will be compiled into this (simplified) IL (with optimizations enabled)

 call IsEverythingOk brfalse.s AfterIfBody ... if body 

Using a local variable

 var ok = IsEverythingOk(); if (ok) { ... } 

you get this optimized (and simplified) IL:

 call IsEverythingOk stloc.0 ldloc.0 brfalse.s AfterIfBody ... if body 

The surface seems a little less efficient as the return value is stored on the stack and then popped, but the JIT compiler also performs some optimizations.

You can see the actual machine code generated by debugging your application with native code debugging enabled. You must do this using the release build, and you will also have to disable the debugger option, which suppresses JIT optimization when loading the module. Now you can put breakpoints in the code you want to test, and then view the disassembly. Please note that JIT is like a black box, and the behavior that I see on my computer may be different from what other people see on their computers. Given this disclaimer, the build code I get for both versions of the code (with a slight difference in how the call is made):

 call IsEverythingOk test eax,eax je AfterIfBody 

Thus, JIT optimizes excess unnecessary IL. In fact, in my initial experiments, the IsEverythingOk method returned true , and the JIT was able to fully optimize the branch. When I then switched to returning the field in the method, the JIT would make a direct call and immediately access the field.

On the bottom line: you should expect JIT to optimize at least simple things, such as transient local variables, even if the code generates some extra IL that seems redundant.

+5
source

The compiler, of course, generates some additional IL code steps if you use the first solution, since it requires at least additional stloc and ldloc , but if it's just for performance reasons, forget these microseconds (or nanoseconds).

If there is no other reason for the ok variable, I would prefer the second solution nonetheless, as that would be easier to read.

+1
source

I would say that this is a preference if you do not have a single coding standard. One of the others gives an advantage.

This is great if you expect or expect a modification other than the if clause. Although it creates a stack entry when the variable is created, it will be deleted remotely after the method area.

 bool ok = IsEverythingOK(); if(ok) { //do somehthing } 

This is great if you want to use it only as a check. Although it is only good if your method name is short. But let me say that you are accessing the class before using it like _myLongNameInstance.IsEverythingOK () , which reduces readability, and I will go with the first one, but with different conditions I would choose the direct if.

 if(IsEverythingOK()) { //do somehthing } 
+1
source

Source: https://habr.com/ru/post/1206537/


All Articles