dense_hash_map的复杂key的用法
比较了std::map和boost::unordered_map; 后者性能略胜前者。
准备使用dense_hash_map试试。
简单的例子见http://www.cnblogs.com/dreamcs/articles/1782340.html
官方的例子有
#include <iostream> #include <google/dense_hash_map> using google::dense_hash_map; // namespace where class lives by default using std::cout; using std::endl; using ext::hash; // or __gnu_cxx::hash, or maybe tr1::hash, depending on your OS struct eqstr { bool operator()(const char* s1, const char* s2) const { return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0); } }; int main() { dense_hash_map<const char*, int, hash<const char*>, eqstr> months; months.set_empty_key(NULL); months["january"] = 31; months["february"] = 28; months["march"] = 31; months["april"] = 30; months["may"] = 31; months["june"] = 30; months["july"] = 31; months["august"] = 31; months["september"] = 30; months["october"] = 31; months["november"] = 30; months["december"] = 31; cout << "september -> " << months["september"] << endl; cout << "april -> " << months["april"] << endl; cout << "june -> " << months["june"] << endl; cout << "november -> " << months["november"] << endl; }
起初因为很好用,很简单的例子嘛。但是我的项目里面是一用一对string作为key的,换了一把不好使。
不知道这个dense_hash_map怎么用了,晕菜。
To: google-sparsehash@googlegroups.com Subject: Re: std::pair usage in google sparse hash References: <e403a8fc-b94b-45eb-bc32-3cdcad1d9...@s21g2000prm.googlegroups.com> From: Craig Silverstein <csilv...@google.com> Date: Fri, 11 Sep 2009 14:38:13 -0700 In-Reply-To: <e403a8fc-b94b-45eb-bc32-3cdcad1d9...@s21g2000prm.googlegroups.com> (Shankar's message of "Fri\, 11 Sep 2009 14\:34\:31 -0700 \(PDT\)") Message-ID: <m3ljklduwq....@meta.mtv.corp.google.com> User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-System-Of-Record: true } Is there an alternative implementation which doesnot use std::pair ? There is not. However, sparse_hash_map is a pretty thin wrapper around sparsehashtable. You could write your own wrapper around sparsehashtable with not that much code, and replace pair<> with the data structure of your choice. I don't think you'll need to modify the sparsehashtable code at all.
直到我发现了http://code.google.com/p/google-sparsehash/issues/detail?id=58&can=1,调试了一把,发现可以,于是我猜测单单实现一个比较器不行,必须自己实现一个pair的hash。于是搞定了。
inline unsigned int BKDRHash(const string& str, const string& str2) { unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. unsigned int hash = 0; for(std::size_t i = 0; i < str.size(); i++) { hash = (hash * seed) + str[i]; } hash = (hash * seed) + '\t'; for(std::size_t i = 0; i < str2.size(); i++) { hash = (hash * seed) + str2[i]; } return hash; } struct pairKeyHash { size_t operator()(const pair<string,string>& p1) const { return BKDRHash(p1.first, p2.second); } }; struct pairKeyEq { size_t operator()(const pair<string,string>& p1, const pair<string,string>& p2) const { return p1 == p2; } }; int main() { dense_hash_map<const string, string, pairKeyHash, pairKeyEq > test_map; test_map.set_empty_key(make_pair("","")); test_map[make_pair("1","1")] = "A"; cout << "1 -> " << months[make_pair("1","1")] << endl; return 0; }
搞定了,不过测试起来没看出这个map有多快,哎,难道是我的hash算法不行!