What's better to use and why? - c++

class MyClass {
private:
unsigned int currentTimeMS;
public:
void update() {
currentTimeMS = getTimeMS();
// ...
}
};
class MyClass {
public:
void update() {
unsigned int currentTimeMS = getTimeMS();
// ...
}
};
update() calls in main game loop so in the second case we get a lot of allocation operations (unsigned int currentTimeMS). In the first case we get only one allocate and use that allocated variable before.
Which of this code better to use and why?

I recommend the second variant because it is stateless and the scope of the variable is smaller. Use the first one only if you really experience a performance issue, which I consider unlikely.
If you do not modify the variable value later, you should also consider to make it const in order to express this intent in your code and to give the compiler additional optimization options.

It depends upon your needs. If currentTimeMS is needed only temporarily in the update(), then surely declare it there. (in your case, #option2)
But if it's value is needed for the instance of the class (i.e. being used in some other method), then you should declare it as a field (in your case, #option1).

In the first example, you are saving the state of this class object. In the second one, you're not, so the currentTime will be lost the instant update() is called.
It is really up to you to decide which one you need.

The first case is defining a member variable the second a local variable. Basic class stuff. A private member variable is available to any function (method) in that class. a local variable is only available in the function in which it is declared.

Which of this code better to use and why?
First and foremost, the cited code is at best a tiny micro-optimization. Don't worry about such things unless you have to.
In fact, this is most likely a disoptimization. Sometimes automatic variables are allocated on the stack. Stack allocation is extremely fast (and even free sometimes). There is no need to worry. Other times, the compiler may place a small automatic variable such the unsigned int used here in a register. There's no allocation whatsoever.
Compare that to making the variable a data member of the class, and solely for the purpose of avoiding that allocation. Accessing that variable involves going through the this pointer. Pointer dereference has a cost, potentially well beyond that of adding an offset to a pointer. The dereference might result in a cache miss. Even worse, this dereferencing may well be performed every time the variable is referenced.
That said, sometimes it is better to create data members solely for the purpose of avoiding automatic variables in various member functions. Large arrays declared as local automatic variables might well result in stack overflow. Note, however, that making double big_array[2000][2000] a data member of MyClass will most likely make it impossible to have a variable of type MyClass be declared as a local automatic variable in some function.
The standard solution to the problems created by placing large arrays on the stack is to instead allocate them on the heap. This leads to another place where creating a data member to avoid a local variable can be beneficial. While stack allocation is extremely fast, heap allocation (e.g., new) is quite slow. A member function that is called repeatedly may benefit by making the automatic variable std::unique_ptr<double> big_array = std::make_unique<double>(2000*2000) a data member of MyClass.
Note that neither of the above applies to the sample code in the question. Note also that the last concern (making an heap-allocated variable a data member so as to avoid repeated allocations and deallocations) means that the code has to go through the this pointer to access that memory. In tight code, I've sometimes been forced to create a local automatic pointer variable such as double* local_pointer = this->some_pointer_member to avoid repeated traversals through this.

Related

Should I declare a variable used in many functions as a member variable?

I have many overloaded functions in a class. In this case, should I declare the int32_t data as a member variable of the class, so I am not declaring it over and over in each function? The Fill function is always setting a value through reference, so I don't think I should need to declare it every time in every function.
There is about 20 more of these functions not listed here:
void TransmitInfo(TypeA &dp, Id &tc)
{
//do lots of other work here
int32_t data;
while (dp.Fill(data)) //Fill accepts a reference variable, "data" gets populated
{
Transmit(tc, data);
}
}
void TransmitInfo(TypeB &dp, Id &tc)
{
//do lots of other work here
int32_t data;
while (dp.Fill(data))
{
Transmit(tc, data);
}
}
void TransmitInfo(TypeC &dp, Id &tc)
{
//do lots of other work here
int32_t data;
while (dp.Fill(data))
{
Transmit(tc, data);
}
}
Scope is not the only thing to consider when choosing where to declare a variable. Just as important are the lifetime of the variable and when it is created.
When you declare a variable inside a function, it is created whenever that function is called, several times if need be (recursion!). And it's destroyed when that function exits. These creations/destructions are noops for the CPU in the case of simple types as int32_t.
When you declare it inside the class, you get only one copy of the variable per object you create. If one of your function calls another (or itself), they will both use the same variable. You also increase the size of your objects; your variable will consume memory even when it's not used.
So, the bottom line is: Use the different kinds of variables for the purposes they were designed for.
If a function needs to remember something while it runs, it's a function variable.
If a function needs to remember something across its invocations, it's a static function variable.
If an object needs to remember something across its member invocations, it's a member variable.
If a class needs to remember something across all objects, it's a static class variable.
Anything else leads to chaos.
You should refrain from using a member variable for any type of temporary data. The reason for this is that it guarantees that your code is not thread safe, and in this day-and-age of parallel computing, that is a major disadvantage. The cost of allocating an int32_t is extremely small as to be negligible so thus it is often better to allocate inside the function to maintain thread safety. Before a single int allocation becomes noticeable you will have to allocate it well over a million times, and even then the total loss will be in microseconds.
If your experiencing such difficulty with optimization that you have to resort to such a high degree of micro-optimization then you likely should try and rework your algorithm to create a better scaling as opposed to spending massive amounts of time optimizing something that is not a choke point. (You would also be better off using a good concurrent algorithm, as opposed to shaving picoseconds off of a serial algorithm.)
Absolutely do not do this. If it's only a temporary for the life of a function then keep it local.
Else you'll cause more problems than you solve; e.g. Multithreading and serialisation.
Leave such micro-optimisations to the compiler.

What's the standard way to avoid constant dereferencing after using `new` keyword?

The new keyword hands you back a pointer to the object created, which means you keep having to deference it - I'm just afraid performance may suffer.
E.g. a common situation I'm facing:
class cls {
obj *x; ...
}
// Later, in some member function:
x = new obj(...);
for (i ...) x->bar[i] = x->foo(i + x->baz); // much dereferencing
I'm not overly keen on reference variables either as I have many *x's (e.g. *x, *y, *z, ...) and having to write &x_ref = *x, &y_ref = *y, ... at the start of every function quickly becomes tiresome and verbose.
Indeed, is it better to do:
class cls {
obj x; ... // not pointer
}
x_ptr = new obj(...);
x = *x_ptr; // then work with x, not pointer;
So what's the standard way to work with variables created by new?
There's no other way to work with objects created by new. The location of the unnamed object created by new is always a run-time value. This immediately means that each and every access to such an object will always unconditionally require dereferencing. There's no way around it. That is what "dereferencing" actually is, by definition - accessing through a run-time address.
Your attempts to "replace" pointers with references by doing &x_ref = *x at the beginning of the function are meaningless. They achieve absolutely nothing. References in this context are just syntactic sugar. They might reduce the number of * operators in your source code (and might increase the number of & operators), but they will not affect the number of physical dereferences in the machine code. They will lead to absolutely the same machine code containing absolutely the same amount of physical dereferencing and absolutely the same performance.
Note that in contexts where dereferencing occurs repeatedly many times, a smart compiler might (and will) actually read and store the target address in a CPU register, instead of re-reading it each time from memory. Accessing data through an address stored in a CPU register is always the fastest, i.e. it is even faster than accessing data through compile-time address embedded into the CPU instruction. For this reason, repetitive dereferencing of manageable complexity might not have any negative impact on performance. This, of course, depends significantly on the quality of the compiler.
In situations when you observe significant negative impact on performance from repetitive dereferencing, you might try to cache the target value in a local buffer, use the local buffer for all calculations and then, when the result is ready, store it through the original pointer. For example, if you have a function that repeatedly accesses (reads and/or writes) data through a pointer int *px, you might want to cache the data in an ordinary local variable x
int x = *px;
work with x throughout the entire function and at the end do
*px = x;
Needless to say, this only makes sense when the performance impact from copying the object is low. And of course, you have to be careful with such techniques in aliased situations, since in this case the value of *px is not maintained continuously. (Note again, that in this case we use an ordinary variable x, not a reference. Your attempts to replace single-level pointers with references achieve nothing at all.)
Again, this sort of "data cashing" optimization can also be implicitly performed by the compiler, assuming the compiler has good understanding of the data aliasing relationships present in the code. And this is where C99-style restrict keyword can help it a lot. But that's a different topic.
In any case, there's no "standard" way to do that. The best approach depends critically on your knowledge of data flow relationships that exist in each specific piece of your code.
Instantiate the object without the new keyword, like this:
obj x;
Or if your constructor for obj takes parameters:
obj x(...);
This will give you an object instead of a pointer thereto.
You have to decide whether you want to allocate your things on heap or on stack. Thats completely your decision based on your requirements. and there is no performance degradation with dereferencing. You may allocate your cls in heap that will stay out of scope and keep instances of obj in stack
class cls {
obj x;//default constructor of obj will be called
}
and if obj doesn't have a default constructor you need to call appropiate constructor in cls constructor

Copy static class member to local variable for optimization

While browsing open source code (from OpenCV), I came across the following type of code inside a method:
// copy class member to local variable for optimization
int foo = _foo; //where _foo is a class member
for (...) //a heavy loop that makes use of foo
From another question on SO I've concluded that the answer to whether or not this actually needs to be done or is done automatically by the compiler may be compiler/setting dependent.
My question is if it would make any difference if _foo were a static class member? Would there still be a point in this manual optimization, or is accessing a static class member no more 'expensive' than accessing a local variable?
P.S. - I'm asking out of curiosity, not to solve a specific problem.
Accessing a property means de-referencing the object, in order to access it.
As the property may change during the execution (read threads), the compiler will read the value from memory each time the value is accessed.
Using a local variable will allow the compiler to use a register for the value, as it can safely assume the value won't change from the outside. This way, the value is read only once from memory.
About your question concerning the static member, it's the same, as it can also be changed by another thread, for instance. The compiler will also need to read the value each time from memory.
I think a local variable is more likely to participate in some optimization, precisely because it is local to the function: this fact can be used by the compiler, for example if it sees that nobody modifies the local variable, then the compiler may load it once, and use it in every iteration.
In case of member data, the compiler may have to work more to conclude that nobody modifies the member. Think about multi-threaded application, and note that the memory model in C++11 is multi-threaded, which means some other thread might modify the member, so the compiler may not conclude that nobody modifies it, in consequence it has to emit code for load member for every expression which uses it, possibly multiple times in a single iteration, in order to work with the updated value of the member.
In this example the the _foo will be copied into new local variable. so both cases the same.
Statis values are like any other variable. its just stored in different memory segment dedicated for static memory.
Reading a static class member is effectively like reading a global variable. They both have a fixed address. Reading a non-static one means first reading the this-pointer, adding an offset to the result and then reading that address. In other words, reading a non-static one requires more steps and memory accesses.

Access member variables directly or pass as parameter?

I noticed that even when paying respect to the single responsibility principle of OOD, sometimes classes still grow large. Sometimes accessing member variables directly in methods feels like having global state, and a lot of stuff exists in the current scope. Just by looking at the method currently working in, it is not possible anymore to determine where invidiual variables accessible in the current scope come from.
When working together with a friend lately, I realized I write much more verbose code than him, because I pass member variables still as parameters into every single method.
Is this bad practice?
edit: example:
class AddNumbers {
public:
int a, b;
// ...
int addNumbers {
// I could have called this without arguments like this:
// return internalAlgorithmAddNumbers();
// because the data needed to compute the result is in members.
return internalAlgorithmAddNumbers(a,b);
}
private:
int internalAlgorithmAddNumbers(int sum1, int sum2) { return sum1+sum2; }
};
If a class has member variables, use them. If you want to pass parameters explicitly, make it a free function. Passing member variables around not only makes the code more verbose, it also violates people's expectations and makes the code hard to understand.
The entire purpose of a class is to create a set of functions with an implicitly passed shared state. If this isn't what you want to do, don't use a class.
Yes, definetely a bad practice.
Passing a member variable to a member function has no sense at all, from my point of view.
It has several disadvantages:
Decrease code readability
Cost in term of performances to copy the parameter on the stack
Eventually converting the method to a simple function, may have sense. In fact, from a performance point of view, call to non-member function are actually faster (doesn't need to dereference this pointer).
EDIT:
Answer to your comment. If the function can perform its job only using a few parameters passed explicitely, and doesn't need any internal state, than probably there is no reason to declare it has a member function. Use a simple C-style function call and pass the parameters to it.
I understand the problem, having had to maintain large classes in code I didn't originally author. In C++ we have the keyword const to help identify methods that don't change the state:
void methodA() const;
Use of this helps maintainability because we can see if a method may change the state of an object.
In other languages that don't have this concept I prefer to be clear about whether I'm changing the state of the instance variable by either having it passed in by reference or returning the change
this->mMemberVariable = this->someMethod();
Rather than
void someMethod()
{
this->mMemberVariable = 1; // change object state but do so in non transparent way
}
I have found over the years that this makes for easier to maintain code.

Will static methods decrease my overhead?

Does a class have to allocate memory for its non-static member functions every time a new instance is created?
To put a finer point on it, if I were writing a class v3d representing 3-space vectors, would I use less memory by defining
static v3d::dotProduct(v3d v1, v3d v2)
as opposed to
v3d::dotProduct(v3d v2) ?
Neither static nor non-static member functions are stored per instance. In the case of non-static member functions, the way I understand it is that they are translated into something like (probably less readable than this):
v3d_dotProduct(v3d this, v3d v2)
And the calls to them are translated accordingly. If you want to improve performance, I would recommend using inline functions as these essentially copy the function contents to the place that you call it. I don't think this will decrease your memory usage, but it's worth using for class functions (static and non-static) which are called many times per second.
http://www.cplusplus.com/forum/articles/20600/
There is one instance of the function in memory. It has nothing to do with static or not. You don't allocate memory for member functions.
Or maybe I misunderstood. Perhaps you meant the function somehow takes up space in the object? No, it doesn't. At the object code level, membership is essentially just a name convention and a hidden 'this' parameter. If virtual, there is typically a single vtable, the same one for all instances.
However, in your examples, you appear to be passing all the v3d objects by value. This means in the static case you're making 2 object copies (one for each arg) and in the non-static case you're making only 1 object copy.
If you passed the args by reference, you could avoid making copies - except as may be required by the dot-product algorithm, whatever that is (a long time since I did any mathematics).
In either case the function's code only has a single copy in code memory. Static functions use the same amount of code memory but use less stack memory because when they are called one less argument is passed on the stack. Non-static class member functions have an additional argument (the this pointer) that is added to the stack when called. If you don't use anything in the object that would necessitate using the "this" pointer, you should declare the function static.
The amount of stack memory you will save is likely trivial. But if the function is called millions of times per second a static function could see an improvement in speed due to not having to pass an additional argument on the stack.