【发布时间】:2012-08-21 14:12:50
【问题描述】:
我使用的是带有std::string 键的地图,虽然一切正常,但我没有获得预期的性能。我搜索了一些可以优化和改进的地方,然后一位同事说,“那个字符串键会很慢。”
我读了几十个问题,他们一直说:
“不要使用
char *作为键”
“std::string密钥永远不是你的瓶颈”
“char *和std::string是一个神话。”
我很不情愿地尝试了char * 键,但还是有区别,很大的区别。
我把问题归结为一个简单的例子:
#include <stdio.h>
#include <stdlib.h>
#include <map>
#ifdef USE_STRING
#include <string>
typedef std::map<std::string, int> Map;
#else
#include <string.h>
struct char_cmp {
bool operator () (const char *a,const char *b) const
{
return strcmp(a,b)<0;
}
};
typedef std::map<const char *, int, char_cmp> Map;
#endif
Map m;
bool test(const char *s)
{
Map::iterator it = m.find(s);
return it != m.end();
}
int main(int argc, char *argv[])
{
m.insert( Map::value_type("hello", 42) );
const int lcount = atoi(argv[1]);
for (int i=0 ; i<lcount ; i++) test("hello");
}
首先是 std::string 版本:
$ g++ -O3 -o test test.cpp -DUSE_STRING
$ time ./test 20000000
real 0m1.893s
接下来是 'char *' 版本:
g++ -O3 -o test test.cpp
$ time ./test 20000000
real 0m0.465s
这是一个相当大的性能差异,与我在大型程序中看到的差异大致相同。
使用char * 键在释放键时很痛苦,而且感觉不对。 C ++专家我错过了什么?有什么想法或建议吗?
【问题讨论】:
-
正如您刚才所展示的,始终对所有笼统的陈述持保留态度。
-
您的测试可能不是 std::string 和 char* 之间的公平比较。在您的“char *”版本的 Map 中,您没有将内存分配给您的键,而您的“std::string”版本的 Map,每次都会为键分配一个新的字符串。
-
我刚刚意识到我的第一条评论是一揽子声明。
-
您的自定义比较器功能版本更优雅iff您已经拥有 C 字符串。如果您不打算使用 std::string 获得的所有“类型安全/无需手动分配”的时髦,那么它并不是很有趣。 C++ 让你只为你使用的东西付费。如果你问我,这是对 std::map 灵活性的致敬
-
@LokiAstari:不总是,不。对于一些非常特别受限的情况,您必须靠近金属。
标签: c++ performance dictionary stdmap