Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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++_C_Pointers_Local_Dereference - Fatal编程技术网

C++ C结构指针解引用速度

C++ C结构指针解引用速度,c++,c,pointers,local,dereference,C++,C,Pointers,Local,Dereference,我有一个关于指针解引用速度的问题。我有一个这样的结构: 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) .

我有一个关于指针解引用速度的问题。我有一个这样的结构:

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) ...
}
TD_RECT*pRect;
...
对于(i=0;ileft)。。。
如果(p[i].x>pRect->right)。。。
如果(p[i].ytop)。。。
如果(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) ...
}
TD_RECT*pRect;
左双=预切->左;
双顶部=预切割->顶部;
双右=预切->右;
双层底=预制->底部;
...
对于(i=0;i正确)。。。
如果(p[i].y底部)。。。
}

因此,在案例1中,循环直接解引用pRect指针以获得比较值。在案例2中,在函数的局部空间(堆栈上)上生成新值,并将这些值从pRect复制到局部变量。通过一个循环,将有许多比较

在我看来,它们同样慢,因为局部变量也是堆栈上的内存引用,但我不确定

另外,最好是继续通过索引引用p[],或者通过一个元素增加p,并在没有索引的情况下直接取消对它的引用


有什么想法吗?谢谢:)

我认为第二种情况可能会更快,因为您没有在每次循环迭代中取消引用指向pRect的指针


实际上,进行优化的编译器可能会注意到这一点,并且生成的代码可能没有差异,但pRect作为p[]中某个项的别名的可能性可能会阻止这种情况发生。

您可能会发现它与现代编译器没有什么区别。它们中的大多数可能会执行公共子表达式,以消除循环中不变的表达式。假设C语句和汇编代码之间存在简单的一对一映射是不明智的。我见过gcc输出的代码会让我的汇编技能相形见绌

但是这不是C和C++问题,因为ISO标准并没有规定它是如何完成的。最好的检查方法是使用类似于
gcc-S
的代码生成汇编程序代码,并详细检查这两种情况

如果你远离这种微观优化,更多地关注宏观层面,如算法选择等,你的投资也会获得更多回报


和所有优化问题一样,测量,不要猜测!有太多的变量会影响它,因此您应该在目标环境中使用实际数据对不同的方法进行基准测试。

优化编译器将看到结构访问是循环不变的,因此,使您的两个案例看起来相同。

这不太可能是性能关键性的巨大差异。您可以对每个选项进行多次配置,然后查看。确保在测试中设置了编译器优化

关于存储双打,使用const可能会影响性能。你的阵列有多大

关于使用指针算法,这可以更快,是的

如果你知道你的直肠左<右,你可以立即优化(肯定是这样)。如果xright,所以你可以加上一个“else”

如果有的话,你最大的优化来自于不必遍历数组中的所有项,也不必对所有项执行4次检查


例如,如果在x和y上对数组进行索引或排序,则可以使用二进制搜索查找所有x<左的值,并仅循环这些值

如果即使是一个完全未优化的编译(-O0)也会为这两种情况生成不同的代码,我会感到惊讶。为了在现代处理器上执行任何操作,需要将数据加载到寄存器中。因此,即使在声明自动变量时,这些变量也不会存在于主内存中,而是存在于某个处理器的浮点寄存器中。即使你自己不声明变量,这也是正确的,因此我也不期望生成的机器代码有任何差异,即使你在C++代码中声明临时变量时也是如此。
但正如其他人所说,将代码编译到汇编程序中,自己看看。

不要浪费时间进行过早优化,因为过早优化很可能不会带来一点变化。也许一点变化的分数很重要,但如果重要,为什么不测量它呢?对于Win32,我可以使用GetTickCount()吗要测量调用循环前后的时间以测量速度,或者有更好的方法吗?@user482910您可以,但请确保平均多次(比如一百万次以上)运行,因为程序运行时上下文切换到另一个进程的可能性很小。“我想念MSDOS”-现在有三个词我从没想过我会再听到:-)我问,因为我写的函数是为包含数百万个顶点的向量贴图剪裁多边形。。。我能挤出的任何一点速度都会有帮助,因为我需要将每个部分裁剪成1度的区域。这很好。正确的做法是运行真实世界的基准测试,因为它取决于大量因素,而我们知道的因素很少。至少,您的目标机器、编译器、CPU、其他体系结构问题,如内存和I/O子系统、数据的组成、优化级别等等。如果您有数百万个目标机器,请参阅下面我的评论。在矢量图上创建一个索引(即p?),按x和y排序。(它是否保持相当静止?)。或者在x上排序,在y上有一个索引。使用二进制搜索查找所有xright,所有ybottom。所以,如果你说400万,这是22个比较,总共88个,而不是你现在的1600万!向量图的每一部分都是在特定的区域中构造的