long way or short way?
If i''m writing a function that is going to reference some deep things (nested structures), and use an array index that is also deeply nested, is it better to store the index or use the longer notation (would that be faster/slower)?
EXAMPLE: which is better?
int blabla(ptr)
{
ptr->ptr->ptr[ptr->ptr->index].something = 1;
}
int blabla(ptr)
{
int index = ptr->ptr->index; //store index first
ptr->ptr->ptr[index].something = 1;
//consider also that i might use the index more than once
}
thanx in advance!
Most compilers should optimize this down to basically the same thing, regardless of which way you type it in. So in general, which ever way is more readable to you, go with that.
Jonathan
Jonathan
Go with the second format IF you''re using the same thing more than once, with other snippets in between. This saves the compiler the trouble of writing code for indirection each time...
Ignore VGASteve. Jon''s right.
Do whatever is most readable to you. I often use "helper references" whenever I have to deref more than two levels.
Do whatever is most readable to you. I often use "helper references" whenever I have to deref more than two levels.
Depending on which compiler you''re using, it''ll try to optimize it. Generally, I think (well, I agree with Andre LaMothe''s book TOTWGPG) that shorter lines of code produce better, faster assembly. If you program really, really complex lines, then the compiler will always produce assembly code that works, but maybe not necessarily as fast of code as if you had broken it up into several lines. Here''s word-for-word what LaMothe''s book says:
"Program in a RISC-like (Reduced Instruction Set Computer) manner. In other words, make your code simple rather than complex. Pentium and Pentium II processors in particular like simple instructions rather than complex ones. And making your code longer, with simpler instructions, makes it easier for the compiler. For example, don''t do this:
if ((x+=(2*buffer[index++])>10)
{
// do work
} // end if
Do this:
x += (2 * buffer[index]);
index++;
if (x > 10)
{
// do work
} // end if
There are two reasons for coding like this. First, it allows a debugger to put break points between code sections. Second, it makes it easier for the compiler to send simplified code to the Pentium, which allows it to process more code in parallel using multiple execution units. Complex code is bad!"
I couldn''t have said it better myself...
ColdfireV
"Program in a RISC-like (Reduced Instruction Set Computer) manner. In other words, make your code simple rather than complex. Pentium and Pentium II processors in particular like simple instructions rather than complex ones. And making your code longer, with simpler instructions, makes it easier for the compiler. For example, don''t do this:
if ((x+=(2*buffer[index++])>10)
{
// do work
} // end if
Do this:
x += (2 * buffer[index]);
index++;
if (x > 10)
{
// do work
} // end if
There are two reasons for coding like this. First, it allows a debugger to put break points between code sections. Second, it makes it easier for the compiler to send simplified code to the Pentium, which allows it to process more code in parallel using multiple execution units. Complex code is bad!"
I couldn''t have said it better myself...
ColdfireV
[email=jperegrine@customcall.com]ColdfireV[/email]
In this case LaMothe has a point with regards to allowing additional debugging lines. More lines in debug the better.
However, he''s not correct about efficiency being any greater splitting it up into multiple segments. If you compile those two fragments with optimizations turned on, it will emit the same machine code. (Plus or minus some INT 3''s in debug mode.)
For the original code, it doesn''t matter, because a properly optimizing compiler will create a series of DAGs (directed acyclic graphs) showing calculation dependincies. ptr->ptr->index will show up in multiple DAGs, so it''s value will be computed and then cached somehow after unification is performed. The caching will either be in a register (for short lifespan variables) or in a temporary variable. For older (stupider) compilers, this may not be done as efficiently.
However, he''s not correct about efficiency being any greater splitting it up into multiple segments. If you compile those two fragments with optimizations turned on, it will emit the same machine code. (Plus or minus some INT 3''s in debug mode.)
For the original code, it doesn''t matter, because a properly optimizing compiler will create a series of DAGs (directed acyclic graphs) showing calculation dependincies. ptr->ptr->index will show up in multiple DAGs, so it''s value will be computed and then cached somehow after unification is performed. The caching will either be in a register (for short lifespan variables) or in a temporary variable. For older (stupider) compilers, this may not be done as efficiently.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement