C ++ 11:为什么这个范围循环会将FPS降低35?

时间:2013-04-07 16:55:31

标签: c++ performance c++11

我正在使用SFML和C ++ 11功能编写游戏,例如范围循环。在处理平铺地图时,我基本上为每个地图平铺创建了一个类,一个轻量级类,只包含其精灵,位置等,然后构建一些嵌套向量来表示游戏地图图层。

为了优化在屏幕上一次绘制数千个对象的过程,我只是简单地绘制了玩家看到的内容。这很顺利。

我有以下渲染游戏地图的方法,如果图块位置在相机边界内,条件基本上返回

void gameMap::render(sf::RenderWindow &winMain, sf::Vector2f offset) {
      for(vector<int> vec1 : backgroundData)
           for(int i : vec1)
              if(collides(i.pos, offset)
                 myWindow.draw(i.sprite);

     }

它工作正常,但在游戏中我大致得到30 FPS,并且有很多粗糙的动作。但令我惊讶的是,下面的代码执行相同的操作,呈现相同数量的平铺精灵,但以65 fps 运行,并且运动非常流畅

void gameMap::render(sf::RenderWindow &winMain, sf::Vector2f offset) {
          for(int i = 0; i < backgroundTiles.size(); i++)
               for(int j = 0; j < backgroundTiles[i].size(); j++)
                  if(collides(backgroundTiles[i][j].pos, offset)
                     myWindow.draw(backgroundTiles[i][j].sprite);

         }

为什么会这样? C ++ 11基于范围的循环比旧学校慢得多吗?我真的很想听到这个问题的答案,因为我的眼睛真的更喜欢基于范围的循环,我不想发现基于范围的循环慢两倍。

1 个答案:

答案 0 :(得分:58)

外部循环正在复制backgroundData中包含的每个向量:

  for(vector<int> vec1 : backgroundData)

将其更改为以下任一项:

  for(vector<int>& vec1 : backgroundData)
  for(const vector<int>& vec1 : backgroundData)

这会使vec1成为向量的引用,而不是副本。由于矢量复制起来很昂贵,而参考文献使用起来很便宜,这将显着提高性能。

至于非constconst参考之间的选择,我会随时使用后者。

更通用的替代方法是写

  for(auto&& vec1 : backgroundData)

这会为vec1包含的任何类型创建自动类型引用backgroundData。在此上下文中,&&最终会vec1绑定到任何:rvalue引用,引用或const引用,具体取决于backgroundData返回的类型。 [帽子提示给@Yakk提供此建议]