【问题标题】:The fastest way to iterate through a collection of objects迭代对象集合的最快方法
【发布时间】:2010-03-18 04:29:17
【问题描述】:

首先给你一些背景知识:我有一些执行蒙特卡罗模拟的研究代码,重要的是我遍历一组对象,从它们的表面计算一些向量,然后对于我遍历的每个向量再次收集对象以查看矢量是否击中另一个对象(类似于光线追踪)。伪代码看起来像这样

for each object {
    for a number of vectors {
        do some computations
        for each object {
            check if vector intersects
        }
    }
}

由于对象的数量可能非常大,而光线的数量甚至更大,我认为优化迭代对象集合的方式是明智的。我创建了一些测试代码来测试数组、列表和向量,并且在我的第一个测试用例中发现向量迭代器的速度大约是数组的两倍,但是当我在代码中实现向量时,它比我之前使用的数组要慢一些。

所以我回到测试代码并增加了每个循环调用的对象函数的复杂性(一个相当于“检查向量是否相交”的虚拟函数),我发现当函数的复杂性增加执行时间时数组和向量之间的差距缩小,直到最终数组更快。

有人知道为什么会这样吗?循环内部的执行时间会影响外部循环的运行时间,这似乎很奇怪。

【问题讨论】:

  • “由于对象的数量可能非常大,而光线的数量甚至更大,我认为优化对象集合的迭代方式是明智的。” - 我认为您在这种情况下的一般反应应该是优化算法(替换为具有更好复杂性的算法)。你可以随心所欲地优化冒泡排序的循环机制,但随着集合大小的增长,快速排序同样会击败它。
  • 算法无法进一步优化,但我正在同时执行此操作。由于通过对象的大量迭代,我认为这会给我一些简单的运行时间减少。然而,它所做的只是给我留下了一个问题,即为什么向量迭代时间会受到它调用的函数的复杂性或运行时间的影响。

标签: c++ optimization iteration


【解决方案1】:

您测量的是从数组和向量访问元素的开销差异。 (以及它们的创建/修改等...取决于您正在执行的操作)。

编辑:它会因您使用的平台/操作系统/库而异。

【讨论】:

  • 是的,我同意有些实现是不同的。作为旁注,我通过 XCode 使用 GCC。我仅测量循环的执行时间,例如在查看数组时我得到循环每一侧的时间: for(int j = 0; j doSomething() ;我虽然访问数组元素和递增向量迭代器的开销是相同的(一条指令)。这也应该是一个固定成本,而不是随着对象函数的运行时间而变化。
  • 每次你这样做:你改变j的值,计算x[j]的地址,然后访问函数。当你有一个向量迭代器时,x[j] 的地址是从 x[j-1] (x++) 计算出来的,所以它只需要 1 条指令。
  • 提高性能应该做的是:begin=&x[0];结束=&x[...]; for(your_type *ptr=begin; x != end; x++) { ptr->doSomething();}
【解决方案2】:

这可能取决于向量迭代器的实现。一些实现比其他实现更好。 (Visual C++——至少是旧版本——我在看着你。)

【讨论】:

    【解决方案3】:

    我认为我看到的时间差异实际上是由于指针处理代码中的错误。在进行了一些修改以使代码更具可读性之后,无论容器如何,迭代都花费了大约时间(给或取 1%)。这是有道理的,因为所有容器都具有相同的访问机制。

    但是我确实注意到向量在 OpenMP 架构中运行得有点慢,这可能是由于每个线程维护自己的迭代器副本的开销。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 2023-04-11
      • 2012-03-03
      • 2023-03-23
      • 2022-07-05
      • 1970-01-01
      相关资源
      最近更新 更多