我正在开发游戏。我将游戏对象存储在此地图中:
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
在地图中搜索要慢得多?
答案 0 :(得分:6)
计算CRC肯定比任何单个字符串比较慢,但是你可以期望在找到密钥之前进行log2N比较(例如1000个密钥的10次比较),所以它取决于{{{{ 1}}。 CRC也可能导致冲突,因此容易出错(您可以检测到相对容易检测的冲突,甚至可能处理它们以获得正确的结果,但您必须非常小心才能正确)。
如果您的C ++环境提供了一个,那么您可以尝试 map
(可能称为unordered_map<>
) - 它可能会更快,也可能不会更快重复。哈希地图是另一个妥协:
(傻点,但如果你可以继续使用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比使用字符串更快......