将变量延迟报告是否更有效?

Eug*_*e K 3 c++ variables performance

是否需要更多内存或计算效率更快地声明变量?

例:

int x;
code
..
.
.
. x is able to be used in all this code
.
actually used here
.
end
Run Code Online (Sandbox Code Playgroud)

code
..
.
.
.
int x;
actually used here
.
end
Run Code Online (Sandbox Code Playgroud)

谢谢.

Fle*_*exo 9

写出逻辑上最有意义的东西(通常更接近使用).编译器可以并且将会发现这样的事情并生成对目标体系结构最有意义的代码.

你的时间是远远比试图第二猜测编译器的交互和处理器上的高速缓存更有价值.


例如在x86上这个程序:

#include <iostream>

int main() {
  for (int j = 0; j < 1000; ++j) {
    std::cout << j << std::endl;
  }
  int i = 999;
  std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

相比:

#include <iostream>

int main() {
  int i = 999;
  for (int j = 0; j < 1000; ++j) {
    std::cout << j << std::endl;
  }
  std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

编译:

g++ -Wall -Wextra -O4 -S measure.c
g++ -Wall -Wextra -O4 -S measure2.c
Run Code Online (Sandbox Code Playgroud)

diff measure*.s给出检查输出时给出:

<       .file   "measure2.cc"
---
>       .file   "measure.cc"
Run Code Online (Sandbox Code Playgroud)

即使是:

#include <iostream>

namespace {
  struct foo {
    foo() { }
    ~foo() { }
  };
}

std::ostream& operator<<(std::ostream& out, const foo&) {
  return out << "foo";
}

int main() {
  for (int j = 0; j < 1000; ++j) {
    std::cout << j << std::endl;
  }
  foo i;
  std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

VS

#include <iostream>

namespace {
  struct foo {
    foo() { }
    ~foo() { }
  };
}

std::ostream& operator<<(std::ostream& out, const foo&) {
  return out << "foo";
}

int main() {
  foo i;
  for (int j = 0; j < 1000; ++j) {
    std::cout << j << std::endl;
  }
  std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

g++ -S文件名产生的组件差异的结果仍然相同,因为没有副作用.如果有副作用那么这将决定你构建对象的位置 - 你想在什么时候发生副作用?

  • 对于`你的时间比试图再次猜测编译器和处理器上的缓存的相互作用更有价值.我希望更多的人能让这项技术继续优化99%的代码并继续使用某些东西更有成效! (4认同)

K-b*_*llo 5

对于诸如此类的基本类型int,从性能的角度来看并不重要.对于class类型,变量定义也包括构造函数调用,如果控制流跳过该变量,则可以省略该调用.此外,无论是基础还是class类型,如果有足够的信息使这种变量有意义,那么定义应该至少延迟到这一点.对于非默认的可构造类类型,这是强制性的; 对于其他类型,它可能不是,但它会强制您使用未初始化的状态(如-1或其他无效值).您应该在尽可能小的范围内尽可能晚地定义变量; 从性能的角度来看,它有时并不重要,但它在设计方面总是很重要.


Ker*_* SB 5

通常,您应该声明使用变量的位置和时间.它提高了可恢复性,可维护性,并且出于纯粹的实际原因,还提高了内存位置.

即使你有一个大的对象并且你在循环体外部或内部声明它,唯一的区别在于构造和赋值之间; 实际的内存分配几乎是相同的,因为现代分配器非常擅长短期分配.

您甚至可以考虑创建新的匿名范围,如果您有一小部分代码后来不需要变量(尽管这通常表明您最好使用单独的函数).

所以基本上,写出它最符合逻辑的方式,你通常也会得到最有效的代码; 或者至少你不会做任何比通过在顶部宣布一切更糟糕的事情.