Check current value before assignment in set method - c++

I'll start from a code snipped of an application I found over the internet. It's made in C++ but the topic could be addressed to any programming language:
class AppSettings
{
public:
AppSettings() {m_value = 0;}
~AppSettings();
void AppSettings::setValue(uint value)
{
if (m_value != value)
m_value = value;
}
private:
uint m_value;
};
Do you really need to check that the current value differs from the new one before assignment?
Is it just a programming style, efficiency, good manner, or what?
General speaking, in set method of a class, do you need to check that new value differs from current one?

This largely depends on the type of the member being assigned. If it's a primitive type or something equally lightweight, the check is most likely a pessimisation: the assignment is likely to be significantly cheaper than the conditional jump. Remember that basically all modern processors are pipeline-based, and conditional jumps can result in the pipeline needing to be aborted if branch prediction fails. This kills efficiency.
If the type is much more costly to assign, the answer is not so clear-cut. Copying a large buffer of data, for example, is an expensive operation. However, so is comparing it for equality. To make the call on whether to assign blindly or compare first, you need to understand the idiosynracies of the type in question, and evaluate how often same-value assignments are likely to happen, how quick they are to identify, and how costly this identification is compared to copying "blindly." Also bear in mind that if the comparison indicates they the values are different, you will have paid for both: the comparison, and then the copy.
Finally, there are cases when the check is necessary: when the assignment has a side effect. For example, if the type of the member is such that it emits a notification whenever assigned to, you will most likely need the comparison to avoid spurious notifications (assuming you don't want those, of course).
In all, there is no hard-and-fast rule, but I would say that on average, you should only include the comparison if you have good reason for it.

Do you really need to check that the current value differs from the new one before assignment? Is it just a programming style, efficiency, good manner, or what?
It looks like cruft to me.
You usually end up with code like this, when you mix two ideas while writing the code ("We only update state when necessary" vs. "the setter just sets the value"), and the sample code ends up not expressing either idea clearly.
I cannot say though - I would have to read the article you took the code from.
General speaking, in set method of a class, do you need to check that new value differs from current one?
You do, when you either optimize, or when the idea you need to express in code is "perform updates when necessary".
Consider this (artificial and contrieved) code:
/// object in 2D space
class TwoDObject
{
/// shift object position
void shift_position(int x, int y)
{
if(x != x_ || y != y_)
{
x_ = x;
y_ = y;
render_shadows();
}
}
private:
// render the shadows cast by this object (slow implementation)
void render_shadows();
int x_;
int y_;
};
In this case, you have an internal state update, followed by side effects (shadows have changed when you changed position).
Because the method to render the shadows is slow, you only want to call it when necessary.

It really depends on what you are setting, what I mean, It is important to do it if you are setting things that will propagate changes. If the cost of that change is quite big(reorder an entire array, update data in some network place, rewrite a big file) in this cases, and if the program needs real time performance, it is a good practice to check unnecesary changes. If the change has no side-effects is better just change it and avoid extra branching.

Related

Understanding cost of multiple . and -> operator use?

Out of habit, when accessing values via . or ->, I assign them to variables anytime the value is going to be used more than once. My understanding is that in scripting languages like actionscript, this is pretty important. However, in C/C++, I'm wondering if this is a meaningless chore; am I wasting effort that the compiler is going to handle for me, or am I exercising a good practice, and why?
public struct Foo
{
public:
Foo(int val){m_intVal = val;)
int GetInt(){return m_intVal;}
int m_intVal; // not private for sake of last example
};
public void Bar()
{
Foo* foo = GetFooFromSomewhere();
SomeFuncUsingIntValA(foo->GetInt()); // accessing via dereference then function
SomeFuncUsingIntValB(foo->GetInt()); // accessing via dereference then function
SomeFuncUsingIntValC(foo->GetInt()); // accessing via dereference then function
// Is this better?
int val = foo->GetInt();
SomeFuncUsingIntValA(val);
SomeFuncUsingIntValB(val);
SomeFuncUsingIntValC(val);
///////////////////////////////////////////////
// And likewise with . operator
Foo fooDot(5);
SomeFuncUsingIntValA(fooDot.GetInt()); // accessing via function
SomeFuncUsingIntValB(fooDot.GetInt()); // accessing via function
SomeFuncUsingIntValC(fooDot.GetInt()); // accessing via function
// Is this better?
int valDot = foo.GetInt();
SomeFuncUsingIntValA(valDot);
SomeFuncUsingIntValB(valDot);
SomeFuncUsingIntValC(valDot);
///////////////////////////////////////////////
// And lastly, a dot operator to a member, not a function
SomeFuncUsingIntValA(fooDot.m_intVal); // accessing via member
SomeFuncUsingIntValB(fooDot.m_intVal); // accessing via member
SomeFuncUsingIntValC(fooDot.m_intVal); // accessing via member
// Is this better?
int valAsMember = foo.m_intVal;
SomeFuncUsingIntValA(valAsMember);
SomeFuncUsingIntValB(valAsMember);
SomeFuncUsingIntValC(valAsMember);
}
Ok so I try to go for an answer here.
Short version: you definitely don’t need to to this.
Long version: you might need to do this.
So here it goes: in interpreted programs like Javascript theese kind of things might have a noticeable impact. In compiled programs, like C++, not so much to the point of not at all.
Most of the times you don’t need to worry with these things because an immense amount of resources have been pulled into compiler optimization algorithms (and actual implementations) that the compiler will correctly decide what to do: allocate an extra register and save the result in order to reuse it or recompute every time and save that register space, etc.
There are instances where the compiler can’t do this. That is when it can’t prove multiple calls produce the same result. Then it has no choice but to make all the calls.
Now let’s assume that the compiler makes the wrong choice and you as a precaution make the effort of micro–optimizations. You make the optimization and you squish a 10% performance increase (which is already an overly overly optimistic figure for this kind of optimization) on that portion of code. But what do you know, your code spends only 1% of his time in that portion of code. The rest of the time is most likely spend in some hot loops and waiting for data fetch. So you spend a non-negligible amount of effort to optimize yourself the code only to get a 0.1% performance increase in total time, which won’t even be observable due to the external factors that vary the execution time by way more than that amount.
So don’t spend time with micro-optimizations in C++.
However there are cases where you might need to do this and even crazier things. But this is only after properly profiling your code and this is another discussion.
So worry about readability, don’t worry about micro–optimizations.
The question is not really related to -> and . operators, but rather about repetitive expressions in general. Yes, it is true that most modern compilers are smart enough to optimize the code that evaluates the same expression repeatedly (assuming it has no observable side-effects).
However, using an explicit intermediate variable typically makes the program much more readable, since it explicitly exposes the fact that the same value is supposed to be used in all contexts. It exposes the fact the it was your intent to use the same value in all contexts.
If you repeat using the same expression to generate that value again and again, this fact becomes much less obvious. Firstly, it is difficult to say at the first sight whether the expressions are really identical (especially when they are long). Secondly, it is not obvious whether sequential evaluations of the seemingly the same expression produce identical results.
Finally, slicing long expressions into smaller ones by using intermediate variables can significantly simply debugging the code in step-by-step debugger, since it give the user much greater degree of control through "step in" and "step over" commands.
It's for sure better in terms of readability and maintainability to have such temporary variable.
In terms of performance, you shouldn't worry about such micro-optimization at this stage (premature optimization). Moreover, modern C++ compilers can optimize it anyway, so you really shouldn't worry about it.

Copy value into consts for optimization

Assume that your first objective is execution speed, then code cleanliness and finally usage of resources.
If at a certain point of an algorithm a variable (for instance a double) is not going to change any more (but you are still going to read it many times), would you copy it into a constant value?
If you want to make your code clearer, by all means, copy your values into a const double const_value = calculated_value;, but compilers are very good at tracking dependencies, and it's highly unlikely (assuming you are using a modern, reasonably competent compiler) that the code will be any faster or otherwise "better" because you do this. There is a small chance that the compiler takes your word for the fact that you want a second variable, and thus makes a copy, and makes the code slower because of that.
As always, if performance is important to your application, make a "before & after" comparative benchmark for your particular code, as reading a page on the internet or asking on SO is not the same as benchmarking your code.
Just copying non-constant variable into a constant one does not make the code cleaner because instead of one variable you have two. Much more interesting would be to move non-constant one out-of-scope. This way, we have only constant version of the variable visible and compiler prevents us from changing its value by mistake.
Herb Sutter describes how to do this using C++11 lambdas: Complex initialization for a const variable.
const int i = [&]{
int i = some_default_value;
if(someConditionIstrue)
{
Do some operations and calculate the value of i;
i = some calculated value;
}
return i;
} ();
(I don't explain execution speed objective since it is already done by Mats Petersson).
For better code readability, you can create a const reference to the variable at the point where it isn't changed anymore, and use the const reference from that point on.
double value_init;
// Some code that generates value_init...
const double& value = value_init;
// Use value from now on in your algorithm

Function calls vs. local variables

I often see functions where other functions are called multiple times instead of storing the result of the function once.
i.e (1):
void ExampleFunction()
{
if (TestFunction() > x || TestFunction() < y || TestFunction() == z)
{
a = TestFunction();
return;
}
b = TestFunction();
}
Instead I would write it that way, (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 to read and better to debug.
But I'm wondering why people do it like in number 1?
Is there anything I don't see? Performance Issue?
When I look at it, I see in the worst case 4 function calls in number (1) instead of 1 function call in number (2), so performance should be worse in number (1), shouldn't it?
I'd use (2) if I wanted to emphasize that the same value is used throughout the code, or if I wanted to emphasize that the type of that value is int. Emphasizing things that are true but not obvious can assist readers to understand the code quickly.
I'd use (1) if I didn't want to emphasize either of those things, especially if they weren't true, or if the number of times that TestFunction() is called is important due to side-effects.
Obviously if you emphasize something that's currently true, but then in future TestFunction() changes and it becomes false, then you have a bug. So I'd also want either to have control of TestFunction() myself, or to have some confidence in the author's plans for future compatibility. Often that confidence is easy: if TestFunction() returns the number of CPUs then you're happy to take a snapshot of the value, and you're also reasonably happy to store it in an int regardless of what type it actually returns. You have to have minimal confidence in future compatibility to use a function at all, e.g. be confident that it won't in future return the number of keyboards. But different people sometimes have different ideas what's a "breaking change", especially when the interface isn't documented precisely. So the repeated calls to TestFunction() might sometimes be a kind of defensive programming.
When a temporary is used to store the result of a very simple expression like this one, it can be argued that the temporary introduces unecessary noise that should be eliminated.
In his book "Refactoring: Improving the Design of Existing Code", Martin Fowler lists this elimination of temporaries as a possibly beneficial refactoring (Inline temp).
Whether or not this is a good idea depends on many aspects:
Does the temporary provides more information than the original expression, for example through a meaningful name?
Is performance important? As you noted, the second version without temporary might be more efficient (most compilers should be able to optimize such code so that the function is called only once, assuming it is free of side-effects).
Is the temporary modified later in the function? (If not, it should probably be const)
etc.
In the end, the choice to introduce or remove such temporary is a decision that should be made on a case by case basis. If it makes the code more readable, leave it. If it is just noise, remove it. In your particular example, I would say that the temporary does not add much, but this is hard to tell without knowing the real names used in your actual code, and you may feel otherwise.
The second option is clearly superior.
You want to emphasize and ensure that you have three times the same value in the if-statement.
Performance should not be a bottleneck in this example. In conclusion minimizing the chance for errors plus emphasize same values are much more important then a potential small performance gain.
The two are not equivalent. Take for example:
int TestFunction()
{
static int x;
return x++;
}
In a sane world though, this wouldn't be the case, and I agree that the second version is better. :)
If the function, for some reason, can't be inlined, the second will even be more efficient.
I think version 2 is much better to read and better to debug.
Agreed.
so performance should be worse in number (1), shouldn't it?
Not necessarily. If TestFunction is small enough, then the compiler may decide to optimize the multiple calls away. In other cases, whether performance matters depends on how often ExampleFunction is called. If not often, then optimize for maintainability.
Also, TestFunction may have side-effects, but in that case, the code or comments should make that clear in some way.

variables as opposed to class calls

I have recently learned that if you have a reference to a class as a function parameter, it is better practice and more efficient to store certain needed pieces of information as local variables rather than accessing the classes members every time you need them in the function.
so...
void function(const Sphere& s)
{
//lots of calls to s.centre and s.radius
}
or
void function(const Sphere& s)
{
Vector3 centre = s.centre; float radius = s.radius;
//an equal amount of calls to centre and radius
}
I am told the second is better, but why? And also, where is a good place to start researching this more fully? (for dummys please!)
Whoever told you this probably thought that the second version was likely to be faster.
I think this is bad advice, for two reasons:
It may or may not actually be faster. This depends on the compiler, on what exactly the code is doing etc.
Even if it is faster, this screams premature optimization. One should micro-optimize only after profiling the code and establishing which part of the code is the overall bottleneck.
The concept is intuitive, but wrong. The concept is that accessing members takes more calculations than local variables, so by converting members to variables, you save performance.
But this is wrong. Your compiler will optimize this in ways you could never imagine. Don't attempt to be smarter than the compiler.
This could actively be dangerous. If s.centre or s.radius change during the execution of this function (say due to a function you call or another thread), you will end up with two inconsistent, old values in your local variables -- causing bugs. Even if you're doing this safely, why take the chances of introducing bugs when you can just refer back to the canonical variables themselves?
You were lied to. Moreover, you should not be worrying about such minutiae unless you have profiled your code and found this to be a main source of inefficiency in your code. Don't try to outsmart your compiler's optimizer. It is better at optimizing your code than you are.
Here is a general outlook of your code:
void function(Sphere s)
{
Vector3 centre = s.centre; float radius = s.radius;
//an equal amount of calls to centre and radius
}
First off, you'd gain much more efficiency by passing Sphere as a const reference. This way, a new copy isn't created, which is probably more expensive than member access. So the way to go is:
void function(const Sphere& s)
{
Vector3 centre = s.centre; float radius = s.radius;
//an equal amount of calls to centre and radius
}
Secondly, you shouldn't access members of classes directly. It may be easy now, but in a large project it's really hard to debug. You should use inline getters and setters. That way, the generated code is the same, but you have a single entry point.
Thirdly, this version isn't thread safe. What if a different thread changes s? s.center and s.radius would change, but you'd still be operating on the old values.
Lastly, compilers do a better job at optimizing than you can, so it's better to leave this one up to the compiler.
Whoever told you that is wrong. You can improve performance by using inline functions. Also in your example use
void function(Sphere &s)
Saves using the copy constructor.

How to avoid out parameters?

I've seen numerous arguments that using a return value is preferable to out parameters. I am convinced of the reasons why to avoid them, but I find myself unsure if I'm running into cases where it is unavoidable.
Part One of my question is: What are some of your favorite/common ways of getting around using an out parameter? Stuff along the lines: Man, in peer reviews I always see other programmers do this when they could have easily done it this way.
Part Two of my question deals with some specific cases I've encountered where I would like to avoid an out parameter but cannot think of a clean way to do so.
Example 1:
I have a class with an expensive copy that I would like to avoid. Work can be done on the object and this builds up the object to be expensive to copy. The work to build up the data is not exactly trivial either. Currently, I will pass this object into a function that will modify the state of the object. This to me is preferable to new'ing the object internal to the worker function and returning it back, as it allows me to keep things on the stack.
class ExpensiveCopy //Defines some interface I can't change.
{
public:
ExpensiveCopy(const ExpensiveCopy toCopy){ /*Ouch! This hurts.*/ };
ExpensiveCopy& operator=(const ExpensiveCopy& toCopy){/*Ouch! This hurts.*/};
void addToData(SomeData);
SomeData getData();
}
class B
{
public:
static void doWork(ExpensiveCopy& ec_out, int someParam);
//or
// Your Function Here.
}
Using my function, I get calling code like this:
const int SOME_PARAM = 5;
ExpensiveCopy toModify;
B::doWork(toModify, SOME_PARAM);
I'd like to have something like this:
ExpensiveCopy theResult = B::doWork(SOME_PARAM);
But I don't know if this is possible.
Second Example:
I have an array of objects. The objects in the array are a complex type, and I need to do work on each element, work that I'd like to keep separated from the main loop that accesses each element. The code currently looks like this:
std::vector<ComplexType> theCollection;
for(int index = 0; index < theCollection.size(); ++index)
{
doWork(theCollection[index]);
}
void doWork(ComplexType& ct_out)
{
//Do work on the individual element.
}
Any suggestions on how to deal with some of these situations? I work primarily in C++, but I'm interested to see if other languages facilitate an easier setup. I have encountered RVO as a possible solution, but I need to read up more on it and it sounds like a compiler specific feature.
I'm not sure why you're trying to avoid passing references here. It's pretty much these situations that pass-by-reference semantics exist.
The code
static void doWork(ExpensiveCopy& ec_out, int someParam);
looks perfectly fine to me.
If you really want to modify it then you've got a couple of options
Move doWork so that's it's a member of ExpensiveCopy (which you say you can't do, so that's out)
return a (smart) pointer from doWork instead of copying it. (which you don't want to do as you want to keep things on the stack)
Rely on RVO (which others have pointed out is supported by pretty much all modern compilers)
Every useful compiler does RVO (return value optimization) if optimizations are enabled, thus the following effectively doesn't result in copying:
Expensive work() {
// ... no branched returns here
return Expensive(foo);
}
Expensive e = work();
In some cases compilers can apply NRVO, named return value optimization, as well:
Expensive work() {
Expensive e; // named object
// ... no branched returns here
return e; // return named object
}
This however isn't exactly reliable, only works in more trivial cases and would have to be tested. If you're not up to testing every case, just use out-parameters with references in the second case.
IMO the first thing you should ask yourself is whether copying ExpensiveCopy really is so prohibitive expensive. And to answer that, you will usually need a profiler. Unless a profiler tells you that the copying really is a bottleneck, simply write the code that's easier to read: ExpensiveCopy obj = doWork(param);.
Of course, there are indeed cases where objects cannot be copied for performance or other reasons. Then Neil's answer applies.
In addition to all comments here I'd mention that in C++0x you'd rarely use output parameter for optimization purpose -- because of Move Constructors (see here)
Unless you are going down the "everything is immutable" route, which doesn't sit too well with C++. you cannot easily avoid out parameters. The C++ Standard Library uses them, and what's good enough for it is good enough for me.
As to your first example: return value optimization will often allow the returned object to be created directly in-place, instead of having to copy the object around. All modern compilers do this.
What platform are you working on?
The reason I ask is that many people have suggested Return Value Optimization, which is a very handy compiler optimization present in almost every compiler. Additionally Microsoft and Intel implement what they call Named Return Value Optimization which is even more handy.
In standard Return Value Optimization your return statement is a call to an object's constructor, which tells the compiler to eliminate the temporary values (not necessarily the copy operation).
In Named Return Value Optimization you can return a value by its name and the compiler will do the same thing. The advantage to NRVO is that you can do more complex operations on the created value (like calling functions on it) before returning it.
While neither of these really eliminate an expensive copy if your returned data is very large, they do help.
In terms of avoiding the copy the only real way to do that is with pointers or references because your function needs to be modifying the data in the place you want it to end up in. That means you probably want to have a pass-by-reference parameter.
Also I figure I should point out that pass-by-reference is very common in high-performance code for specifically this reason. Copying data can be incredibly expensive, and it is often something people overlook when optimizing their code.
As far as I can see, the reasons to prefer return values to out parameters are that it's clearer, and it works with pure functional programming (you can get some nice guarantees if a function depends only on input parameters, returns a value, and has no side effects). The first reason is stylistic, and in my opinion not all that important. The second isn't a good fit with C++. Therefore, I wouldn't try to distort anything to avoid out parameters.
The simple fact is that some functions have to return multiple things, and in most languages this suggests out parameters. Common Lisp has multiple-value-bind and multiple-value-return, in which a list of symbols is provided by the bind and a list of values is returned. In some cases, a function can return a composite value, such as a list of values which will then get deconstructed, and it isn't a big deal for a C++ function to return a std::pair. Returning more than two values this way in C++ gets awkward. It's always possible to define a struct, but defining and creating it will often be messier than out parameters.
In some cases, the return value gets overloaded. In C, getchar() returns an int, with the idea being that there are more int values than char (true in all implementations I know of, false in some I can easily imagine), so one of the values can be used to denote end-of-file. atoi() returns an integer, either the integer represented by the string it's passed or zero if there is none, so it returns the same thing for "0" and "frog". (If you want to know whether there was an int value or not, use strtol(), which does have an out parameter.)
There's always the technique of throwing an exception in case of an error, but not all multiple return values are errors, and not all errors are exceptional.
So, overloaded return values causes problems, multiple value returns aren't easy to use in all languages, and single returns don't always exist. Throwing an exception is often inappropriate. Using out parameters is very often the cleanest solution.
Ask yourself why you have some method that performs work on this expensive to copy object in the first place. Say you have a tree, would you send the tree off into some building method or else give the tree its own building method? Situations like this come up constantly when you have a little bit off design but tend to fold into themselves when you have it down pat.
I know in practicality we don't always get to change every object at all, but passing in out parameters is a side effect operation, and it makes it much harder to figure out what's going on, and you never really have to do it (except as forced by working within others' code frameworks).
Sometimes it is easier, but it's definitely not desirable to use it for no reason (if you've suffered through a few large projects where there's always half a dozen out parameters you'll know what I mean).