【问题标题】:Optimization Vector of vector of object seems slow对象向量的优化向量似乎很慢
【发布时间】:2015-09-17 10:53:17
【问题描述】:

我正在创建一个多人视频游戏以供娱乐,我有一个服务器和一个客户端正在运行。 我想尽可能优化服务器上​​的流程。当我们同时收到来自不同客户端的大量信息时,服务器会滞后。

我想和你核实一下我所做的是否可以优化,我觉得很容易。

代码如下:

我们有一张地图:

std::vector< std::vector < caseMap > >  _map;

一个简单的对象caseMap:

struct caseMap
{
    int                     areaId;
    bomb                    *bombs;
    Bonus                   *bonus;
    int                     underEffect;
    int                     effectOwnerId;
    std::list< player* >    players;
};

在此操作之后,我们会花费大量时间来映射案例: (例如当玩家死亡时)

this->_map[pl->getPosY()][pl->getPosX()].players.erase(itp);

有我的问题和解决方案: - 我们可以只有一个向量而不是两个向量,并且有一个小公式来检索我们正在寻找的实际案例。

但是像我现在这样使用它很重吗?我认为通过 [] 访问是大 O 常数,所以它不应该超重。

我可以在某个时候使用一些 const 引用吗?

我应该使用不同的对象,例如 std::map 吗?

如果你们能在 c++ 代码上刷新我的大脑,我有点困惑。 谢谢你:)

【问题讨论】:

  • 查找时间是固定的。你把时间浪费在小事上。 “过早的优化是万恶之源”——Donald Knuth。
  • 先分析和测量,选择实际需要优化的部分。
  • 您需要知道与 STL 数据结构相关的开销很大:一个包含 10 个项目的 std::vector 比仅由 10 个项目使用的内存成本(多一点),这这是由于 STL 簿记所使用的数据结构以及操作员 new[]/malloc() 簿记所使用的数据结构。一般来说,如果有大量元素,“嵌套”STL 类(例如vector)不是一个好主意,因为开销会变得很大(也就是说,我同意@jcoffland)
  • 您是如何得出您在那里花费大量时间的结论的?您是否在此处保留列表以查找地图给定区域上的玩家?你与多少玩家打交道?
  • 如何优化这取决于更广泛的架构。让我印象深刻的是你取消了很多指针。指针可能意味着非连续存储,并且在某些情况下,非连续存储可能比连续存储慢得多。立即浮现在脑海的问题是: list&lt;player*&gt; 可以替换为vector&lt;player*&gt;吗?你必须为球员使用指针吗?或者您可以将 实际 播放器对象存储在您的 caseMap> aka vector&lt;player&gt; players 中吗?

标签: c++ dictionary optimization vector


【解决方案1】:

对于std::vector,查找时间始终保持不变。而且常数很小。向向量添加更多元素是O(1) 摊销时间,正如 cmets 中所指出的那样。但请注意,最坏​​情况的附加时间是O(n)。不过,这通常不是问题。如果您知道您需要的空间多于您可以通过调用std::vector::reserve() 来使其稍快一些来预先分配它。但这通常也是不必要的优化。

std::map 具有 O(ln(x)) 查找和插入时间,因此在大多数情况下会更慢。

如果您遇到性能问题,这不是原因。您应该保留此代码。尝试做一些花哨的事情可能会导致代码变慢和维护混乱。

“过早的优化是万恶之源”——Donald Knuth

请参阅问题whats-the-best-free-c-profiler-for-windows,了解用于分析代码的几个选项。完成您的代码。然后对其进行分析并专注于优化重要的部分。

另一个很好的报价:

“把它做好。然后让它快点。”

对于年轻程序员和一些老程序员来说,这是最难学习的课程之一。您认为自己在做正确的事情并且确实使代码变得很棒,但您主要是在旋转轮子优化无关紧要的事情并造成未来的代码维护问题。

【讨论】:

  • std::vector 的末尾添加元素不是O(N^2)。添加一个元素是O(1)(摊销,见cs.stackexchange.com/questions/9380/…),添加N个元素是O(N)。当然,reserve() 仍然是个好主意。
  • 谢谢你们的回答,很高兴谈论它,我一直认为我可能走错了路,很高兴听到更有经验的程序员的建议。谢谢。
  • @Markus Mayr,好点子。在std::vector 的末尾添加一个元素仍然是 O(N) 最坏的情况。这并不重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-22
  • 1970-01-01
  • 2019-10-31
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
相关资源
最近更新 更多