Two C++ efficiency questions
1. Is the use of the static keyword an efficient way avoid variables from being destroyed and re-created in functions that are frequently called? For example, if during an idle function (which is called many many times per second), you have a variable that keeps the present time
void idle()
{
TimeObject time = GetTime();
// idle stuff
}
Would it be more efficient to declare TimeObject as a static, as there is no reason for the object to be destroyed when it goes out of scope. The first time it is used it is re-assigned a value anyway, so its old value has no impact whatsoever. Or is there some overhead inherent to static variables that I am unaware of? And is the same true of static built-in types, such as ints?
2. I know that there is an overhead associated with dynamically allocating memory. My question is, though, is that overhead mostly in the creation of the new object(s) (ala constructors), or is there also significant time required to set aside the necessary block of memory?
Thanks in advance!
1) For primitives allocating variables on the stack takes effectively no time at all, and using the static variable will probably not do good things to the cache. On the other hand, for classes with a non-primitive constructor it may save time, but again will still not be cache friendly. However, this falls firmly in the realm of micro-optimization. There are better things to concentrate your time on.
2) For most general memory allocators, allocating memory takes an appreciable amount of time. In general that time rises with the number of allocations that have already been performed. Your compiler may ship with special case memory allocators that make small allocations faster, however.
2) For most general memory allocators, allocating memory takes an appreciable amount of time. In general that time rises with the number of allocations that have already been performed. Your compiler may ship with special case memory allocators that make small allocations faster, however.
It's not related to efficiency, but I'll point out that if you use static variables in functions, and if you ever decide to start multi-threading, you'll probably wind up with some hard-to-track-down bugs. Every access to static variables would have to be protected in some way or another (usually with mutexes). Usually this doesn't happen, and the function itself is documented as not being thread safe. At this point, it is up to the code calling the function, rather than the function itself, to ensure that chaos does not occur.
So if only for the sake of preserving safety, readability, and ease-of-use, I'd recommend not using statics as you described, even if they provided a bit of a performance boost.
So if only for the sake of preserving safety, readability, and ease-of-use, I'd recommend not using statics as you described, even if they provided a bit of a performance boost.
static function variable is an overall incorrect (insufficient) solution in multithreaded design
Kuphryn
Kuphryn
One other thing to be aware of with static variables is that most compilers effectively insert a global bool and an if when you declare a static so they know whether to call the constructor or not, something like this:
You write:
static TimeObject time;
The compiler generates:
// in statically allocated memory somewhere
TimeObject static_time_from_idle_function;
bool has_time_from_idle_function_been_initialized = false;
// in your function
if(!has_time_from_idle_function_been_initialized)
{
new (&static_time_from_idle_function) TimeObject();
has_time_from_idle_function_been_initialized = true;
}
So if your constructor is trivial you'll actually end up paying more for the cost of the check every time through the function than you pay by constructing the object every call.
You write:
static TimeObject time;
The compiler generates:
// in statically allocated memory somewhere
TimeObject static_time_from_idle_function;
bool has_time_from_idle_function_been_initialized = false;
// in your function
if(!has_time_from_idle_function_been_initialized)
{
new (&static_time_from_idle_function) TimeObject();
has_time_from_idle_function_been_initialized = true;
}
So if your constructor is trivial you'll actually end up paying more for the cost of the check every time through the function than you pay by constructing the object every call.
Quote:Original post by CyberSlag5k
1. Is the use of the static keyword an efficient way avoid variables from being destroyed and re-created in functions that are frequently called?
It also has the side effect of making your function non-reentrant and non thread-safe. It's really just the same thing as using a global, except for the way it is initialized.
I didn't pay attention if anybody mentioned this, but if you declare your time as static, you must understand the consequences.
void idle(){static TimeObject time = GetTime();}
The code above won't do what the original code did. What'll happen is that the GetTime() is called only once during the program execution and that's not what you are after. Of course, it is rather simple to prevent this bug from occuring. Ie. to write the assignment to another line.
Just telling about my experiences with the static keyword and some hours spent on debugging :)
I must also mention, (if you put all that threading stuff aside) that the case I present here is sometimes useful. For example, you might want to make a counter of some sort which you want to initialize once and you want it to be accessible only from that one function.
Cheers
Thanks for the additional info, guys.
And yeah, I meant I'd do something like this:
void idle()
{
static TimeObject time;
time = GetTime();
}
It's a waste of a default constructor call, of course, but that's of little consequence. It was a good thing to point out, however. I could see that causing some serious trouble were it to go unnoticed.
And yeah, I meant I'd do something like this:
void idle()
{
static TimeObject time;
time = GetTime();
}
It's a waste of a default constructor call, of course, but that's of little consequence. It was a good thing to point out, however. I could see that causing some serious trouble were it to go unnoticed.
The moral of the story is: Don't tell the compiler that it has to be static, unless your program actually needs it to be static. You've read above, all the problems this can cause, particularly with threading. But just as importantly, you'd be unnecessarily restricting the compiler, and it is better to let the compiler take care of things.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement