代码有多快

时间:2011-04-08 09:49:43

标签: c++ boost map checksum crc

我正在开发游戏。我将游戏对象存储在此地图中:

std::map<std::string, Object*> mObjects;

std::string是要在代码中进一步查找的对象的键/名称。指向某些对象非常容易,例如:mObjects["Player"] = ...。但是我担心由于在该地图中的每次搜索中分配std :: string而导致速度变慢。所以我决定使用int作为该地图的关键。

第一个问题:那真的会更快吗?

第二,我不想删除我当前访问的对象类型,所以我找到了方法:将crc字符串计算作为键。例如:

Object *getObject(std::string &key)
{
   int checksum = GetCrc32(key);
   return mObjects[checksum];
}

Object *temp = getOject("Player");

或者这是个坏主意?要计算crc,我会使用boost::crc。或者这是个坏主意,校验和的计算比使用密钥类型std::string在地图中搜索要慢得多?

4 个答案:

答案 0 :(得分:6)

计算CRC肯定比任何单个字符串比较慢,但是你可以期望在找到密钥之前进行log2N比较(例如1000个密钥的10次比较),所以它取决于{{{{ 1}}。 CRC也可能导致冲突,因此容易出错(您可以检测到相对容易检测的冲突,甚至可能处理它们以获得正确的结果,但您必须非常小心才能正确)。

如果您的C ++环境提供了一个,那么您可以尝试 map (可能称为unordered_map<>) - 它可能会更快,也可能不会更快重复。哈希地图是另一个妥协:

  • 哈希的时间可能类似于CRC的时间,但是
  • 之后他们经常可以直接寻找价值而不必在普通地图中进行二元树漫步
  • 他们预先处理了一些处理冲突的逻辑。

(傻点,但如果你可以继续使用ints 它们可以是连续的,那么请记住你可以用更快的数组替换查找。如果整数不是'实际上是连续的,但不是特别稀疏,你可以使用稀疏索引,例如10000个短整数的数组,它们是1000个打包记录的索引。)

底线是,如果你足够关心,你应该实施这些替代和基准它们,看看哪种方法最适合你的特定应用,如果它们真的做出任何实质性的改变。在某些情况下,它们中的任何一种都是最好的,如果你不够认真地比较它们,那么它显然意味着它们中的任何一种都可以。

答案 1 :(得分:3)

对于实际性能,您需要分析代码并查看它。但我很想使用hash_map。虽然它不是C ++标准库的一部分,但大多数流行的实现都提供了它。它提供了非常快速的查找。

答案 2 :(得分:3)

  

第一个问题:那真的会更快吗?

是的 - 你要多次比较一个int,而不是多次比较任意长度的潜在大字符串图。

checksum: Or this is bad idea?

绝对不能保证是独一无二的。这是一个等待咬人的错误。

我要做什么:

使用多个集合并拥抱类型安全:

// perhaps this simplifies things enough that t_player_id can be an int?
std::map<t_player_id, t_player> d_players;
std::map<t_ghoul_id, t_ghoul> d_ghouls;
std::map<t_carrot_id, t_carrot> d_carrots;

搜索速度更快,类型更安全。较小的收藏品较小的分配/调整大小....等等......如果您的应用程序非常简单,那么这无关紧要。使用这种方法,并在分析后调整/根据现有程序的需要进行调整。

祝你好运

答案 3 :(得分:1)

如果你真的想知道你必须分析你的代码并看看函数getObject需要多长时间。我个人使用valgrind和KCachegrind在UNIX系统上分析和呈现数据。

我认为使用id会更快。比较int比使用字符串更快......