Efficient C++ Programming Answers
by Curtis Krauskopf
Almost every answer for an efficient programming question can start out with "Well, it depends...". The compiler vendor you use, the optimization settings, the operating system, the speed (and brand) of the CPU, the speed of the RAM memory and dozens of other factors can each affect the outcome of almost every efficiency programming question. The answers here are those that are generally accepted in the industry or can be shown to be true for a wide variety of common C++ compilers.
Q1) What executes faster: ++i or i++, where i is an integer variable?
A1) ++i probably executes faster because i++ would first fetch the value of i, push it on the stack, increment it and then pop the value of i from the stack. In contrast, ++i fetches the value of i, and then increments it. Yes, I'm leaving a lot of detail out and the push/pop cycle can be optimized away for many situations if the optimizer is good enough.
Q2) Which is generally more efficient: a function that returns a reference or a function that does not return a reference?
A2) Functions that don't return a reference are returning the object by value. This is accomplished by using the object's copy constructor. For non-trivial objects, the time and resource cost of copying the object can be easily measured. Functions that return an object by reference only return a pointer to the object. The object the reference points to is not copied.
Q3) What's the deal with inline functions?
A3) The keyword inline is a hint to the compiler that the function should be compiled into the code wherever it is used. This is normally done with a simple function that is called often, such as a getter or setter in a class or struct. The compiler implementer is allowed to ignore the inline hint and substitute a function call instead. Some compilers automatically disable the inlining of functions while debugging.
Q4) Why use the STL sort()
when we have "good old qsort()"?
A4) The following answer is quoted from public.research.att.com:
To a novice,
qsort(array,asize,sizeof(elem),compare);
looks pretty weird, and is harder to understand than
sort(vec.begin(),vec.end());
To an expert, the fact that sort()
tends to be faster than qsort()
for the same elements and the same comparison criteria
is often significant. Also, sort()
is generic, so that it can be used for any reasonable
combination of container type, element type, and comparison
criterion. For example:
struct Record {
string name;
// ...
};
struct name_compare { // compare Records using "name" as the key
bool operator()(const Record& a, const Record& b) const
{ return a.name<b.name; }
};
void f(vector<Record>& vs)
{
sort(vs.begin(), vs.end(), name_compare());
// ...
}
In addition, most people appreciate that sort()
is type safe, that no casts are required to use it,
and that they don't have to write a compare()
function for standard types. The primary reason that
sort() tends to outperform
qsort() is that the comparison
inlines better.
Q5) One programmer wants to sort a linked list using recursion; another programmer wants to do it without recursion. Which one has the better answer?
A5) It depends on the maximum number of items in the linked list. An implementation that uses recursion will eventually run out of stack space if the linked list is long enough. If the number of items in the linked list is relatively small, say around 30 or so, then either solution might be faster but both implementations will be so fast that it's usually not worth optimizing that one little routine. If the number of items in the list could ever be more than 30, then a non-recursive solution would probably be better because it will not run out of stack space when compared with the recursive solution.
Q6) When is an interface "good"?
A6) From parashift.com:
When it provides a simplified view of
a chunk of software, and it is expressed in the vocabulary
of a user (where a "chunk" is normally a class or a
tight group of classes, and a "user" is another developer
rather than the ultimate customer). The "simplified
view" means unnecessary details are intentionally hidden.
This reduces the user's defect-rate. The "vocabulary
of users" means users don't need to learn a new set
of words and concepts. This reduces the user's learning
curve.
|