【发布时间】:2014-06-20 19:55:59
【问题描述】:
this 主题的作者声称,访问从具有固定长度的二维数组转换而来的一维数组比访问原始二维数组要快得多,至少在 C# 中是这样。我想知道这是否也适用于 C/C++。
当使用 3D 数组时,(x, y, z) 处的值是通过三次解除指向数组的指针来获取的:
int val = arr[x][y][z];
但是您可以将数组转换为一维数组并计算每个坐标的索引, 所以代码变为:
int val = arr[SIZE_X * SIZE_Y * z + SIZE_X * y + x];
这会将三个取消引用操作替换为一次取消引用和 3 次乘法和 2 次加法。
问题是:解引用比计算坐标索引慢还是快三倍?
基准测试输出:
3 dimensions: 5s
1 dimension: 14s
1 dimension fast: 4s
代码:
#include <iostream>
#include <time.h>
int main(int argc, char** argv)
{
const int SIZE_X = 750, SIZE_Y = SIZE_X, SIZE_Z = SIZE_X;
const int SIZE_XY = SIZE_X * SIZE_Y;
time_t startTime;
// 3 dimensions
time(&startTime);
int ***array3d = new int **[SIZE_X];
for (int x = 0; x < SIZE_X; ++x)
{
array3d[x] = new int *[SIZE_Y];
for (int y = 0; y < SIZE_Y; ++y)
array3d[x][y] = new int[SIZE_Z];
}
for (int x = 0; x < SIZE_X; ++x)
for (int y = 0; y < SIZE_Y; ++y)
for (int z = 0; z < SIZE_Z; ++z)
array3d[x][y][z] = 0;
for (int x = 0; x < SIZE_X; ++x)
{
for (int y = 0; y < SIZE_Y; ++y)
delete[] array3d[x][y];
delete[] array3d[x];
}
std::cout << "3 dimensions: " << time(0) - startTime << "s\n";
time(&startTime);
int *array1d = new int[SIZE_X * SIZE_Y * SIZE_Z];
for (int x = 0; x < SIZE_X; ++x)
for (int y = 0; y < SIZE_Y; ++y)
for (int z = 0; z < SIZE_Z; ++z)
array1d[x + SIZE_X * y + SIZE_XY * z] = 0;
delete[] array1d;
std::cout << "1 dimension: " << time(0) - startTime << "s\n";
time(&startTime);
array1d = new int[SIZE_X * SIZE_Y * SIZE_Z];
int i = 0;
for (int x = 0; x < SIZE_X; ++x)
for (int y = 0; y < SIZE_Y; ++y)
for (int z = 0; z < SIZE_Z; ++z)
array1d[++i] = 0;
delete[] array1d;
std::cout << "1 dimension fast: " << time(0) - startTime << "s\n";
return 0;
}
结果:3d 比 1 维数组的快速版本更快,只是稍微慢了一点。
编辑: 我将一维数组循环更改为:
for (int z = 0; z < SIZE_Z; ++z)
for (int y = 0; y < SIZE_Y; ++y)
for (int x = 0; x < SIZE_X; ++x)
array1d[x + SIZE_X * y + SIZE_XY * z] = 0;
而且只用了 5 秒,与 3d 版本一样快。
所以访问顺序很重要,而不是维度。我想。
【问题讨论】:
-
有意义的事情并不总是正确的。此类声明需要仔细审查。
-
这就是我问你的原因。
-
我不确定为什么这被标记为不清楚 - 他在问是否在他的第一个代码块中访问
arr的给定元素更快,或者在他的第二个代码块。似乎是一个有效的问题,尽管他可以自己调查。 -
我平衡了不必要的反对票,并鼓励其他人这样做。不仅很清楚这里要问什么,而且在 SO 中还有其他问题,比如这个。如果它是重复的,请将其标记为这样。但我们都应该停止仇恨,如果可以的话,只回答问题。
-
@JustSid: cu·ri·os·i·ty:学习或了解更多关于某事或某人的愿望(Merriam-Webster 在线词典)
标签: c++ c arrays performance