【问题标题】:What is the most efficient way of accessing elements in a C++ container?访问 C++ 容器中元素的最有效方法是什么?
【发布时间】:2014-09-24 17:18:19
【问题描述】:

假设我想按顺序访问 C++ 容器中的所有元素,哪种方式最有效?我在以下示例中说明了我的问题:

std::vector<int> abc;
abc.push_back(3);
abc.push_back(4);
...
...

for(int i=0; i<abc.size(); i++)
{
  abc[i];
}

std::vector<int>::iterator it = abc.begin();
std::vector<int>::iterator itEnd = abc.end();
while(it != itEnd)
{
     (*it);
     it++;
}

如您所见,在这个例子中,使用了两种方法来访问 C++ 容器中的元素,所以很自然的问题是哪一种更有效。谢谢。

【问题讨论】:

  • 询问你的编译器。
  • 您是否想为您的应用程序选择一个以更快地运行?如果是这样,请选择在代码中看起来更好的那个,在看到差异之前不要担心速度。
  • 对于线性遍历整个容器,对于向量,它们是相同的。对于其他数据结构,迭代器将至少与其他方式一样快。这取决于数据结构。
  • @NeilKirk 除非你不听
  • @Manu343726 我严重怀疑它。对于编译器来说,深入观察size() 以使其意识到它正在处理一个经典的数组循环并不是一件容易的事。在大多数情况下,至少在我测量过的情况下,在循环中调用size 肯定会使他的第一个循环比第二个循环慢(他在循环外调用end)。

标签: c++


【解决方案1】:

解决这些问题的最佳方法是执行 100 万次循环并对其进行测试。编译器各不相同。确保在发布模式下对其进行测试。

我使用 ACE,但这里是我如何获得时差的示例。

  // Log how long each module takes.
      ACE_Time_Value    lSendStart;
      ACE_Time_Value    lDifference;

       // Start keeping track of how long this takes
      lSendStart = ACE_OS::gettimeofday();

      // Figure out how long we took.
      lDifference = ACE_OS::gettimeofday() - lSendStart;
       // Log how long we took
      PLALOG_INFO( mLogger, ACE_TEXT( "doProcessing took ") <<lDifference.sec () << ACE_TEXT( "seconds(s) and ") << (lDifference.usec ()) <<
                    ACE_TEXT(" micro second(s) to process." ), "" );

所以获取开始时间,循环一百万次,获取差异,然后以另一种方式执行相同的循环。

我发现的另一件事是,如果你可以使用 c++11 中的 auto,你通常会发现一个比你展示的历史 for 循环更快的循环。

   std::vector<std::string> lNameList; 
   // fill in vector
   for(auto& lSection : lNameList)
   {
      // lSection is not a string
      // DO something with it

   }

【讨论】:

  • 这不一定是一个好的测试。运行第一个循环可能会将容器的重要部分放入 CPU 缓存中,从而导致后续循环执行得非常快。这与在繁重工作中访问容器的用例不匹配,整个工作都是循环的。
  • 如果您对此感到担心,请使用第一个循环对其进行测试,获取时间。关闭应用程序,然后以另一种方式运行它。如果你使用不同的对象,我没有发现这是一个问题。
  • 另外需要注意的是,在我的测试中,length()、size()、empty(),都有不同的性能结果。如果您正在执行 length() == 0 或 size() == 0,则 empty() 表现最佳。
猜你喜欢
  • 2019-06-30
  • 2011-07-17
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-17
相关资源
最近更新 更多