在这种场景下,如何在不违反DRY(Don’t-Repeat-Yourself)原则的情况下优化性能?
假设我正在使用 C++。现在我有以下代码:
int flag;
// ...
while (!TimeToExitLoop()) {
Func();
}
while
循环将被执行大量次,而 Func
是一个时间关键函数,如下所示:
void Func() {
// some big stuff ...
if (flag > 1) {
// logic 1 ...
}
else {
// logic 2 ...
}
}
此外, < code>flag 在 while
循环中不会改变。因此,最好将条件 if
语句移出 while
循环,并为两个条件定义两个单独的函数,如下所示:
int flag;
// ...
if (flag > 1) {
while (!TimeToExitLoop()) {
Func_FlagBiggerThanOne();
}
}
else {
while (!TimeToExitLoop()) {
Func_FlagNoBiggerThanOne();
}
}
但是,这将导致通过 Func_FlagBiggerThanOne
和 Func_FlagNoBiggerThanOne
重复 Func
中的“大东西”:
void Func_FlagBiggerThanOne() {
// big stuff ...
// logic 1 ...
}
void Func_FlagNoBiggerThanOne() {
// big stuff ...
// logic 2 ...
}
这将违反 Don't-Repeat-Yourself 原则。我们不能将“大东西”放在某个函数中,因为调用该函数将比原始的 if
语句更耗时。解决方案之一是为那些大东西定义一个宏,但是如果“逻辑1”和“逻辑2”将使用“大东西”中定义的变量怎么办?尽管宏仍然有效,但这可能会导致代码难看,程序的读者可能会想,“这些变量到底是在哪里定义的?”
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 are those variables defined?"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我有一个最喜欢的古英语习语:“小聪明,大笨蛋”(我一直对此感到内疚)。另一种说法是“不要为小事而烦恼”。
我希望我能找到 SO 的原始引用:“理发来减肥”。
使代码干净,如果你能合理地遵循 DRY,那就这样做。
然后进行性能调整。 我就是这样做的。
如果调用该函数的成本或 IF 语句的成本甚至上升到雷达上,我会感到非常惊讶。
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.
我只是想到一个解决办法。主要思想是使用#ifdef:
所以我们可以这样写主要逻辑:
但是,正如Mike建议的那样,“最好用相对的方式思考,而不是绝对的。如果“大” stuff”无法调优,这样的优化就没用了。
I just think of a solution. The main idea is to use
#ifdef
:So we can write the main logic like this:
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.