Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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++_C_Performance - Fatal编程技术网

C++ 循环还是无循环?(数据集很小,不易更改)

C++ 循环还是无循环?(数据集很小,不易更改),c++,c,performance,C++,C,Performance,假设我有一个已知大小的小矩阵,它的大小在软件的生命周期内不可能改变。如果我需要检查每个矩阵元素,使用循环或手动索引到每个矩阵位置会更有效吗 例如,假设我有一个由3个窗口组成的系统,每个窗口2个窗格。我需要跟踪每个窗格的状态。在我的系统中,只有3个窗口,每个窗口2个窗格 static const int NUMBER_OF_WINDOWS = 3; static const int NUMBER_OF_PANES = 2; static const int WINDOW_LEFT = 0; st

假设我有一个已知大小的小矩阵,它的大小在软件的生命周期内不可能改变。如果我需要检查每个矩阵元素,使用循环或手动索引到每个矩阵位置会更有效吗

例如,假设我有一个由3个窗口组成的系统,每个窗口2个窗格。我需要跟踪每个窗格的状态。在我的系统中,只有3个窗口,每个窗口2个窗格

static const int NUMBER_OF_WINDOWS = 3;
static const int NUMBER_OF_PANES = 2;

static const int WINDOW_LEFT = 0;
static const int WINDOW_MIDDLE = 1;
static const int WINDOW_RIGHT = 2;

static const int PANE_TOP = 0;
static const int PANE_BOTTOM = 1;

paneState windowPanes[NUMBER_OF_WINDOWS][NUMBER_OF_PANES];
以下哪种访问方法更有效

循环版本:

for (int ii=0; ii<NUMBER_OF_WINDOWS; ii++)
{
  for (int jj=0; jj<NUMBER_OF_PANES; jj++)
  {
    doSomething(windowPanes[ii][jj];
  }
}
doSomething(windowPanes[WINDOW_LEFT][PANE_TOP]);
doSomething(windowPanes[WINDOW_MIDDLE][PANE_TOP]);
doSomething(windowPanes[WINDOW_RIGHT][PANE_TOP]);

doSomething(windowPanes[WINDOW_LEFT][PANE_BOTTOM]);
doSomething(windowPanes[WINDOW_MIDDLE][PANE_BOTTOM]);
doSomething(windowPanes[WINDOW_RIGHT][PANE_BOTTOM]);

循环代码会生成分支指令吗?这些指令会比手动访问时生成的指令更昂贵吗?

经典的效率vs.组织。for循环更易于人类阅读,而手动方式更易于机器阅读


我建议您使用循环。因为如果启用了优化,当编译器看到上界是常量时,它实际上会为您生成手动代码。这样你就能两全其美。

首先:你的函数有多复杂?如果是(很可能是这样),那么您不会注意到任何差异

一般来说,顺序调用函数比循环稍微有效一些。但再一次,收益将是如此之小,不值得讨论

请记住,优化编译器会执行循环展开。这实质上是生成代码,使循环旋转的次数减少,同时在每次旋转中做更多的工作(它们将按顺序调用函数2-4次)。当旋转次数较少且固定时,编译器可以轻松地完全消除循环


从清晰和易于修改的角度来看代码。在许多情况下,编译器将执行许多与性能相关的有用技巧。

您可以线性化多维数组

paneState windowPanes[NUMBER_OF_WINDOWS * NUMBER_OF_PANES];

and then

for (auto& pane : windowPanes) {
    doSomething(pane);
}

如果编译器没有对其进行优化,则可以避免额外的循环。

最好使用defines(
#define NUMBER OF_OF_WINDOWS 3
)而不是常量,因为编译器更容易根据我的答案优化for循环。如果您确实想知道,请使用
-s
进行编译并查看程序集。和/或配置两组代码。编译器可以根据
doSomething
“数据集……不可更改”中的代码做出许多不同的选择。直到它发生。