Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 微优化:使用局部变量与类成员进行迭代_C++_Micro Optimization - Fatal编程技术网

C++ 微优化:使用局部变量与类成员进行迭代

C++ 微优化:使用局部变量与类成员进行迭代,c++,micro-optimization,C++,Micro Optimization,我想如果我将迭代变量声明为类成员一次,我会节省一些时间: struct Foo { int i; void method1() { for(i=0; i<A; ++i) ... } void method2() { for(i=0; i<B; ++i) ... } } foo; 你能解释一下性能差异吗 (我需要在Arduino上运行许多简单的并行“过程”,这样的微优化会产生不同。)当您在循环中声明循环变量时,它的范围非常狭窄。编译器可以随时将其保

我想如果我将迭代变量声明为类成员一次,我会节省一些时间:

struct Foo {
  int i;
  void method1() {
    for(i=0; i<A; ++i) ...
  }
  void method2() {
    for(i=0; i<B; ++i) ...
  }
} foo;
你能解释一下性能差异吗


(我需要在Arduino上运行许多简单的并行“过程”,这样的微优化会产生不同。)

当您在循环中声明循环变量时,它的范围非常狭窄。编译器可以随时将其保存在寄存器中,因此它不会被提交到内存中,甚至一次也不会


当您将循环变量声明为实例变量时,编译器没有这种灵活性。它必须将变量保存在内存中,以防某些方法需要检查其状态。例如,如果您在第一个代码示例中这样做

void method2() {
    for(i=0; i<B; ++i) { method3(); }
}
void method3() {
    printf("%d\n", i);
}
void方法2(){
对于(i=0;i
你能解释一下性能差异吗

对于这种性能差异,我能给出的最合理的解释是:

数据成员
i
在全局内存上声明,全局内存不能一直保存在寄存器中,因此,由于范围非常广泛,对它的操作将比对循环变量
i
的操作慢得多(数据成员
i
必须满足类的所有成员函数)

@达里奥补充道:


此外,编译器不能自由地将其临时存储在 注册,因为
method3()
可能会抛出异常离开对象 处于不想要的状态(因为理论上没有人阻止你 写
int k=this->i;for(k=0;ki=k;
。该代码 将几乎和局部变量一样快,但必须保持 当
method3()
抛出时的帐户(我相信在有保证的情况下) 不抛出编译器将使用
-O3
-O4
对其进行优化 (已核实)


“如果我将迭代变量声明为类成员一次,将节省一些时间”这是一个非常奇怪的想法。每次都是
this->i
。我会冒险猜测局部计数器变量只存储在寄存器中,但要知道这些事情,请使用
-save temp
编译并查看程序集。
A
B
是否小于256?那么编译器可能是able在本地情况下使用8位int(在8位MCU上更快)。这一切都是猜测。其想法不是分配额外的堆栈空间和每次调用保存一条指令。
..
做许多不同的事情,但
i
用作低于256(字节大小)的数组索引。此外,编译器不能将其临时存储在寄存器中,因为
method3()
可能引发异常,使对象处于不需要的状态(因为理论上没有人阻止您写入
int k=this->i;)(k=0;ki=k;
该代码的速度几乎与局部变量一样快,但当method3抛出时,您必须考虑到这一点(我相信当有保证它不会抛出时,编译器将使用-O3或-O4对其进行优化。待验证抱歉:)我不想纠正你。我习惯于在答案中添加我的想法,只是因为我喜欢写关于编程的文章。顺便说一句,快速响应+1:为(register int I=0;…)声明
是个好主意吗
然后呢?假设C++11之前的标准,其中
寄存器
说明符没有被弃用。它被弃用是有原因的,原因是它在今天完全无用。
void loop() { // Arduino loops
  foo.method1();
  foo.method2();
}
void method2() {
    for(i=0; i<B; ++i) { method3(); }
}
void method3() {
    printf("%d\n", i);
}