Function calls against local variables

I often see functions where other functions are called several times instead of saving the result of the function once.

ie (1) :

void ExampleFunction() { if (TestFunction() > x || TestFunction() < y || TestFunction() == z) { a = TestFunction(); return; } b = TestFunction(); } 

Instead, I will write this, (2) :

 void ExampleFunction() { int test = TestFunction(); if (test > x || test < y || test == z) { a = test; return; } b = test; } 

I think version 2 is much better read and debug better. But I wonder why people do it like in number 1? I do not see anything? Performance issues? When I look at this, I see that in the worst case, 4 functions call the number (1) instead of 1 function call in the number (2), so the performance should be worse in the number (1), right?

+4
source share
4 answers

I would use (2) if I wanted to emphasize that the same value is used throughout the code or if I would like to emphasize that the type of this value is int . Emphasizing things that are true but not obvious can help readers quickly understand the code.

I would use (1) if I did not want to emphasize any of these things, especially if they were incorrect, or if the number of times that TestFunction() is called, it is important because of side effects.

Obviously, if you emphasize what is currently true, but then in the future TestFunction() changes and becomes false, then you have an error. Therefore, I would also like to have control over TestFunction() own or to have some confidence in the copyright plans for future compatibility. Often this trust is easy: if TestFunction() returns the number of processors, then you will be happy to take a snapshot of the value, and you will also be happy to store it in int no matter what type it actually returns, you should have minimal confidence in future compatibility so that use a function in general, for example. to be sure that in the future it will not return the number of keyboards. But different people sometimes have different ideas about what a β€œbreak” is, especially when the interface is not documented exactly. Therefore, repeated calls to TestFunction() can sometimes be a kind of defensive programming.

+3
source

When a temporary value is used to store the result of a very simple expression like this, it can be argued that the temporary introduces unnecessary noise, which should be eliminated.

In his book "Refactoring: Improving the Design of Existing Code," Martin Fowler lists this exception to a temporary resource as a possible useful refactoring ( Inline temp ).

Whether this is a good idea depends on many aspects:

  • Does temporary information provide more information than the original expression, for example, through a meaningful name?
  • How important is performance? As you noticed, the second version without temporary ones can be more efficient (most compilers should be able to optimize such code so that the function is called only once, assuming that it has no side effects).
  • Is a temporary change later in the function? (If not, it should be const )
  • and etc.

In the end, the choice to introduce or remove such a temporary solution is a decision that must be made in each case. If this makes the code more readable, leave it. If it's just noise, remove it. In your specific example, I would say that the temporary does not add much, but it is hard to say without knowing the real names used in your actual code, and you may feel different.

+2
source

I think version 2 is much better read and debug better.

I agree.

therefore, performance should be worse in number (1), right?

Not necessary. If TestFunction is small enough, then the compiler may decide to optimize several calls. In other cases, whether performance depends on how often ExampleFunction is ExampleFunction . If not often, then optimize for maintainability.

In addition, TestFunction may have side effects, but in this case the code or comments should somehow clarify this.

+1
source

These two are not equivalent. Take for example:

 int TestFunction() { static int x; return x++; } 

In a healthy world, although that would not be the case, and I agree that the second version is better. :)

If a function cannot be built in for some reason, the second will be even more efficient.

+1
source

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


All Articles