我有一个关于指针去引用速度的问题。我有一个这样的结构:
typedef struct _TD_RECT TD_RECT;
struct _TD_RECT {
double left;
double top;
double right;
double bottom;
};我的问题是,其中哪一个会更快,为什么?
案例1:
TD_RECT *pRect;
...
for(i = 0; i < m; i++)
{
if(p[i].x < pRect->left) ...
if(p[i].x > pRect->right) ...
if(p[i].y < pRect->top) ...
if(p[i].y > pRect->bottom) ...
}案例2:
TD_RECT *pRect;
double left = pRect->left;
double top = pRect->top;
double right = pRect->right;
double bottom = pRect->bottom;
...
for(i = 0; i < m; i++)
{
if(p[i].x < left) ...
if(p[i].x > right) ...
if(p[i].y < top) ...
if(p[i].y > bottom) ...
}因此,在案例1中,循环直接取消引用pRect指针以获得比较值。在案例2中,在函数的局部空间(堆栈)上创建了新的值,并将值从pRect复制到局部变量。通过一个循环,将会有许多比较。
在我看来,它们同样缓慢,因为局部变量也是堆栈上的内存引用,但我不确定.
另外,还是继续按索引引用p[]比较好,还是用一个元素增量p直接取消引用它而不使用索引。
有什么想法吗?谢谢:)
发布于 2010-10-21 11:25:27
您可能会发现,这与现代编译器没有什么区别。它们中的大多数可能会对循环中不发生变化的表达式执行常见的子表达式消除。假设C语句和程序集代码之间存在简单的一对一映射是不明智的。我见过gcc抽出来的代码,这会让我的汇编程序技能蒙羞。
但这既不是C问题,也不是C++问题,因为国际标准化组织标准没有规定它是如何做到的。确保检查的最佳方法是使用类似于gcc -S的东西生成汇编程序代码,并详细检查这两种情况。
如果你远离这种微观优化,把更多精力集中在宏观层面,比如算法选择等等,你的投资也会获得更多的回报。
还有,和所有的优化问题一样,测量,不要猜测!影响它的变量太多了,因此您应该在目标环境中并使用实际的数据对不同的方法进行基准测试。
发布于 2010-10-21 11:29:23
这不太可能是一个巨大的性能关键差异。您可以多次对每个选项执行配置文件,然后查看。确保在测试中设置了编译器优化。
关于存储双打,使用const可能会对性能造成一些影响。你的阵列有多大?
关于使用指针算法,这可以更快,是的。
如果你知道左<右在你的直肠(肯定是肯定的),你可以立即优化。如果x< left,它也不能是>右边,所以您可以输入一个“”。
如果有这样的优化,您的大优化将来自于不必循环遍历数组中的所有项,而不必对所有项执行4次检查。
例如,如果在x和y上索引或排序数组,则可以使用二进制搜索找到所有具有x< left的值,然后循环这些值。
发布于 2010-10-21 11:23:20
我认为第二种情况可能更快,因为在每次循环迭代中都没有取消对指向pRect的指针的引用。
实际上,进行优化的编译器可能会注意到这一点,生成的代码可能没有什么不同,但是pRect作为p[]中项的别名的可能性可以阻止这种情况。
https://stackoverflow.com/questions/3986846
复制相似问题