【发布时间】:2013-02-21 09:53:40
【问题描述】:
我正在开发一个基于图块的客户端-服务器游戏。客户端以 3 维 std::vector 保存数据,并在每一帧中将其内容与服务器发送的内容进行比较(我在客户端有一个单独的 std::vector,其中填充了服务器发送的数据)。
现在客户端的地图由 15x11 个图块组成,每个图块包含有关放置在其上的 10 个对象的数据,因此我在 std::vector 中得到 15*11*10 = 1650 个元素。
我正在比较std::vectors 中的数据,如果有变化,我会根据不同之处创建新对象/删除对象/移动对象。我就是这样做的:
std::vector<IdAndPosition> clientIds;
std::vector<IdAndPosition> serverIds;
// Fill client ids
for(unsigned int i = 0; i < m_tiles.size(); i++)
{
for(unsigned int j = 0; j < m_tiles[i].size(); j++)
{
for(unsigned int s = 0; s < m_tiles[i][j].getObjects().size(); s++)
{
clientIds.push_back(IdAndPosition(m_tiles[i][j].getObjectAtPosition(s)->getId(), i, j, s));
}
}
}
// Fill server ids
for(unsigned int i = 0; i < g_gameStateData.m_gameObjects.size(); i++)
{
for(unsigned int j = 0; j < g_gameStateData.m_gameObjects[i].size(); j++)
{
for(unsigned int s = 0; s < g_gameStateData.m_gameObjects[i][j].size(); s++)
{
serverIds.push_back(IdAndPosition(g_gameStateData.m_gameObjects[i][j][s].second, i, j, s));
}
}
}
for (int i = 0; i < serverIds.size(); i++)
{
IdAndPosition& serverId = serverIds[i];
bool found = false;
for(int j = 0; j < clientIds.size(); j++)
{
IdAndPosition& clientId = clientIds[j];
found = serverId.id == clientId.id;
if(found)
break;
}
if(!found)
{
// If not found, create that object
// tileX // tileY
m_tiles[serverId.pos[0]][serverId.pos[1]].addObjectAtPosition(
TGameObjectFactory::createGameObject(g_gameStateData.m_gameObjects[serverId.pos[0]][serverId.pos[1]][serverId.pos[2]].first), // Game object
serverId.pos[2] // Position at stack
);
// And set it's individual id
m_tiles[serverId.pos[0]][serverId.pos[1]].getObjectAtPosition(serverId.pos[2])->setId(g_gameStateData.m_gameObjects[serverId.pos[0]][serverId.pos[1]][serverId.pos[2]].second);
}
}
for (int i = 0; i < clientIds.size(); i++)
{
IdAndPosition& clientId = clientIds[i];
bool found = false;
for(int j = 0; j < serverIds.size(); j++)
{
IdAndPosition& serverId = serverIds[j];
found = serverId.id == clientId.id;
if(found)
break;
}
if(!found)
{
// If not found, create empty object at this position
// tileX // tileY
m_tiles[clientId.pos[0]][clientId.pos[1]].addObjectAtPosition(
TGameObjectFactory::createGameObject(NO_GAME_OBJECT_ID), // Empty game object (we're removing deprecated one)
clientId.pos[2] // Position at stack
);
}
}
问题是由于在调试模式下调用该函数(从 ~90 到 ~20 fps),我的性能大幅下降。我知道每帧都要经过大量数据,但我不知道如何设计它以使其不那么慢。
我在 Visual Studio 2012 中使用了性能分析来找出导致最大性能下降的确切原因,我得到了以下结果:
所以看起来[] operator for std::vector 是主要原因。
【问题讨论】:
-
[](在我的 MSVC++ 中)的调试版本中有边界检查,它在发布中被删除,这可能是它相对如此高的原因.. -
建议使用迭代器而不是索引和运算符[],尤其是在迭代整个向量时。 operator[] 底部的加法通常是乘法和加法。虽然编译器可能优化 operator[],但不能保证。
标签: c++ performance vector