• Advertisement
Sign in to follow this  

Two C++ efficiency questions

This topic is 4229 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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!

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
static function variable is an overall incorrect (insufficient) solution in multithreaded design

Kuphryn

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
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.



Right.
Imagine how the program lies in the memory.
Each process has its own address space.
This address space is mapped onto the virtual address space and this one is mapped onto the physical address space

The program is seperated into 4 sections

code segment: where the code lies
data segment: where all constants, static variables ... lie
heap segment: here are the dynamic allocated objects

stack segment: your program stack

Now in order to use the static variable you have to load its page from the data segment into the cache if it isn t there already.

Now dependent on your machine and its addressing operations you either copy the result of GetTime() directly to object's memory in the cache
or you need to load the content from the stack into a register and move it from the register into the cache.


And as already mention above multithreading will be a problem.
In general avoid static variables, they may lead to hidden bug sometimes, plus they lead the cache trashing if they aren t referenced very often. At least they waste space in the cache (4kb per page in general depending on your OS)


Share this post


Link to post
Share on other sites
Quote:
Original post by CyberSlag5k
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.


Wouldn't programming a copy constructor take care of this and eliminate the possible use of static?

void idle()
{
TimeObject time(GetTime());
}



Share this post


Link to post
Share on other sites
Quote:
Original post by wolverine
Wouldn't programming a copy constructor take care of this and eliminate the possible use of static?
The original code will use in-place initialization, and should produce the same code.

Share this post


Link to post
Share on other sites
Quote:
Original post by wolverine

Wouldn't programming a copy constructor take care of this and eliminate the possible use of static?

void idle()
{
TimeObject time(GetTime());
}


Well that would work, and it would be the same thing semantically, but the point of the static was to avoid re-creating and dstroying the time variable every time the idle function is called. Unless I'm misunderstanding what you're saying, I don't believe that is done here.

Share this post


Link to post
Share on other sites
Programmer time is more valuable than compiler/code time. Shouldn't you be focusing on something of greater impact? Is the entire program finished, thus justify these microoptimizations?

No? Then get back to work!

Share this post


Link to post
Share on other sites
Quote:
Original post by CyberSlag5k
Quote:
Original post by wolverine

Wouldn't programming a copy constructor take care of this and eliminate the possible use of static?

void idle()
{
TimeObject time(GetTime());
}


Well that would work, and it would be the same thing semantically, but the point of the static was to avoid re-creating and dstroying the time variable every time the idle function is called. Unless I'm misunderstanding what you're saying, I don't believe that is done here.


What i was thinking was only in saving a constructor call and avoid using static.

If you do want to avoid the price of having to pay the variable being constructed and destroyed in that function everytime you call it, then static will be of good use (being carefull with the multi-threaded issues pointed out) or to pass that variable as a private class member (although this last option looks kind of ugly to me).

Share this post


Link to post
Share on other sites
Quote:
Original post by Demus79

I didn't pay attention if anybody mentioned this, but if you declare your time as static, you must understand the consequences.

*** Source Snippet Removed ***

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 :)

Cheers


This is not a bug, not according to the C++ Standard. However in your model of how things work it might be.

Share this post


Link to post
Share on other sites
Quote:
Original post by dawidjoubert
This is not a bug, not according to the C++ Standard.

I'm unaware that the C++ standard specified any bugs. Bugs are programmer constructs; they arise not by the definition of the language, but by the program's intended functionality.

CM

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement