Question First
C++中是否有一种优雅的解决方案来防止人们不得不宣布复杂的物体变量,这些变量仅在循环之外循环中使用,以便提高效率?
Detailed explanation
一位同事对我们的守则政策提出了一个有趣的要点,其中指出(原措辞):“这些”总是对变量使用最小范围,并在初始化时宣布变量 < /它们>。
编码指南示例:
// [A] DO THIS
void f() {
...
for (int i=0; i!=n; ++i) {
const double x = calculate_x(i);
set_squares(i, x*x);
}
...
}
// [B] DON T do this:
void f() {
int i;
int n;
double x;
...
for (i=0; i!=n; ++i) {
x = calculate_x(i);
set_squares(i, x*x);
}
...
}
这一切都很好,很好,当然没有错, 直到你从原始类型移到对象。 (对于一个 某些界面 )
示例:
// [C]
void fs() {
...
for (int i=0; i!=n; ++i) {
string s;
get_text(i, s); // void get_text(int, string&);
to_lower(s);
set_lower_text(i, s);
}
...
}
在此, 字符串将被销毁, 它会释放每个循环周期的内存, 然后每个循环的 < code> get_ text code> 函数将不得不为缓冲新分配内存 。
写:
// [D]
string s;
for (int i=0; i!=n; ++i) {
get_text(i, s); // void get_text(int, string&);
to_lower(s);
set_lower_text(i, s);
}
现在缓冲中分配的内存将在循环运行之间保存,我们很可能节省拨款。
disclapeer: n
有比Dev最初预期的更大的趋势,而代码有在性能 does 重要的情况下运行的紧要趋势。
总之,现在“一般”环状结构的更有效方法是 违反代码位置 并宣布复杂的物体“以防万一 ” 。这让我很不安。
请注意,我考虑这样写:
// [E]
void fs() {
...
{
string s;
for (int i=0; i!=n; ++i) {
get_text(i, s); // void get_text(int, string&);
to_lower(s);
set_lower_text(i, s);
}
}
...
}
是 no 的解决方案,因为可读性受到更大的影响!
Thinks furder , get_text
函数的界面无论如何都是非多义的,因为昨天的参数是 so , 一个“好”界面会按值返回 :
// [F]
for (int i=0; i!=n; ++i) {
string s = get_text(i); // string get_text(int);
to_lower(s);
set_lower_text(i, s);
}
在此,我们确实不支付双倍 的记忆分配费,因为极有可能通过RVO从回报值中构建
,因此,对于[F],我们在分配管理费时支付与[C]相同的 。 与 不同,但[C]案例无法优化这一界面变量。
因此, " 坚固 " 底线 坚固 > 似乎是,使用最小范围(可能)损害性能,使用清洁界面 I,至少考虑按价值回报,比那些反射参数 更清洁,将防止优化机会 -- -- 至少在一般情况下是如此。
" 强势 " 问题并不严重,有时为了提高效率,人们不得不放弃干净的守则,问题是,一旦Devs开始发现这类特殊情况,整个《编码指南》(见[A]、[B])就会失去权威。
现在的“强度”问题 < /强度”将是:见第一段。