Suppose that I'm using C++. Now I have the following code:
int flag;
// ...
while (!TimeToExitLoop()) {
Func();
}
The while
loop will be executed a huge number of times, and Func
is a time-critical function like this:
void Func() {
// some big stuff ...
if (flag > 1) {
// logic 1 ...
}
else {
// logic 2 ...
}
}
Also, the value of flag
won't be change within the while
loop. Therefore, it is better to move the conditional if
statement out of the while
loop, and define two separate functions for the two conditions like this:
int flag;
// ...
if (flag > 1) {
while (!TimeToExitLoop()) {
Func_FlagBiggerThanOne();
}
}
else {
while (!TimeToExitLoop()) {
Func_FlagNoBiggerThanOne();
}
}
However, that will result in the repetition of the "big stuff" in Func
by Func_FlagBiggerThanOne
and Func_FlagNoBiggerThanOne
:
void Func_FlagBiggerThanOne() {
// big stuff ...
// logic 1 ...
}
void Func_FlagNoBiggerThanOne() {
// big stuff ...
// logic 2 ...
}
which will violate the Don't-Repeat-Yourself principle. We can not put that "big stuff" in some function because invoking that function will be more time consuming than the original if
statement. One of the solutions is to define a macro for that big stuff, but what if "logic 1" and "logic 2" will use the variables defined in "big stuff"? Though macro still works, that may result in ugly code, the programme's reader might think, "where the heck开发者_如何学JAVA are those variables defined?"
We can not put that "big stuff" in some function because invoking that function will be more time consuming than the original if statement.
I have a favorite Old English idiom: "penny wise pound foolish" (of which I've been guilty). Another way to put it is "don't sweat the small stuff". I wish I could find the original quote on SO: "getting a haircut to lose weight".
Make the code clean, and if you can reasonably follow DRY, do so. Then do your performance tuning. This is how I do it. I would be very surprised if the cost of calling that function, or the cost of the IF statement, even rises onto the radar.
I just think of a solution. The main idea is to use #ifdef
:
#define FUNC() do { \
// big stuff ...
#ifdef FLAG_BIGGER_THAN_ONE \
// logic 1 ... \
#else \
// logic 2 ... \
#endif \
} while(0)
So we can write the main logic like this:
int flag;
// ...
if (flag > 1) {
while (!TimeToExitLoop()) {
#define FLAG_BIGGER_THAN_ONE
FUNC();
#undef FLAG_BIGGER_THAN_ONE
}
}
else {
while (!TimeToExitLoop()) {
FUNC();
}
}
However, just as Mike suggested, "it's better to think in relative terms, rather than absolute. If the "big stuff" can not be tuned, such an optimisation will be useless.
精彩评论