STL性能分析-map与hash_map
hash_map并不属于C++标准, 但是众多的编译器提供商都提供了自己的hash_map的实现, 我们知道hash_map相对map的最大优势是其O(1)的访问时间, 本文使用一个简单的测试来说明map与hash_map实际的性能差异, 并同时给出MS实现STL(VC6)与SGI实现STL在map上的性能差异.
用于测试的小程序完成一段文本的交叉索引的制作, 使用STL可以使得程序相当简化. 下面是使用map的版本, 测试文本使用了MySql 3.23.16的帮助文档manual.txt(1969K).
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
struct Compare {
bool operator()(std::string a, std::string b) const {
return a <>, Compare > MAP;
MAP CrossRef;
char c;
int LineNo = 1;
time_t starttime,endtime;
time(&starttime);
while(Source) {
c = '\0';
while(Source && !(isalpha(c) || '_' == c)) {
Source.get(c);
if(c == '\n') ++LineNo;
}
string aKey(1,c);
while(Source && (isalnum(c) || '_' == c)) {
Source.get(c);
if(isalnum(c) || '_' == c)
aKey += c;
}
Source.putback(c);
if(c)
CrossRef[aKey].push_back(LineNo);
}
time(&endtime);
cout < < "time:" <<>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
struct Compare {
bool operator()(std::string a, std::string b) const {
return a <> > MAP;
MAP CrossRef;
char c;
int LineNo = 1;
time_t starttime,endtime;
time(&starttime);
while(Source) {
c = '\0';
while(Source && !(isalpha(c) || '_' == c)) {
Source.get(c);
if(c == '\n') ++LineNo;
}
string aKey(1,c);
while(Source && (isalnum(c) || '_' == c)) {
Source.get(c);
if(isalnum(c) || '_' == c)
aKey += c;
}
Source.putback(c);
if(c)
CrossRef[aKey].push_back(LineNo);
}
time(&endtime);
cout < < "time:" <<>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
struct Compare {
bool operator()(std::string a, std::string b) const {
return a <> > MAP;
MAP CrossRef;
char c;
int LineNo = 1;
time_t starttime,endtime;
time(&starttime);
while(Source) {
c = '\0';
while(Source && !(isalpha(c) || '_' == c)) {
Source.get(c);
if(c == '\n') ++LineNo;
}
string aKey(1,c);
while(Source && (isalnum(c) || '_' == c)) {
Source.get(c);
if(isalnum(c) || '_' == c)
aKey += c;
}
Source.putback(c);
//if(c)
//CrossRef[aKey].push_back(LineNo);
}
time(&endtime);
cout << "time:" << endtime - starttime << '\n';
}
测试结果:
DEBUG版本:
I/O时间: 6s
hash_map版本: 10s
SGI map版本: 24s
MS map版本: 26s
RELEASE版本(加大了测试文本到20M):
I/O时间: 3s
hash_map版本: 7s
SGI map版本: 14s
MS map版本: 18s
测试结果相当稳定, 连续多次测试, 结果完全一样, 从结果看, hash_map由于其O(1)的访问时间, 完全占据了性能优势, 可惜MS没有提供hash_map用于对比测试, 不过从map的实现上看, SGI的实现也是明显优于MS实现, 快了10%~30%左右.
用于测试的小程序完成一段文本的交叉索引的制作, 使用STL可以使得程序相当简化. 下面是使用map的版本, 测试文本使用了MySql 3.23.16的帮助文档manual.txt(1969K).
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
struct Compare {
bool operator()(std::string a, std::string b) const {
return a <>, Compare > MAP;
MAP CrossRef;
char c;
int LineNo = 1;
time_t starttime,endtime;
time(&starttime);
while(Source) {
c = '\0';
while(Source && !(isalpha(c) || '_' == c)) {
Source.get(c);
if(c == '\n') ++LineNo;
}
string aKey(1,c);
while(Source && (isalnum(c) || '_' == c)) {
Source.get(c);
if(isalnum(c) || '_' == c)
aKey += c;
}
Source.putback(c);
if(c)
CrossRef[aKey].push_back(LineNo);
}
time(&endtime);
cout < < "time:" <<>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
struct Compare {
bool operator()(std::string a, std::string b) const {
return a <> > MAP;
MAP CrossRef;
char c;
int LineNo = 1;
time_t starttime,endtime;
time(&starttime);
while(Source) {
c = '\0';
while(Source && !(isalpha(c) || '_' == c)) {
Source.get(c);
if(c == '\n') ++LineNo;
}
string aKey(1,c);
while(Source && (isalnum(c) || '_' == c)) {
Source.get(c);
if(isalnum(c) || '_' == c)
aKey += c;
}
Source.putback(c);
if(c)
CrossRef[aKey].push_back(LineNo);
}
time(&endtime);
cout < < "time:" <<>
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
struct Compare {
bool operator()(std::string a, std::string b) const {
return a <> > MAP;
MAP CrossRef;
char c;
int LineNo = 1;
time_t starttime,endtime;
time(&starttime);
while(Source) {
c = '\0';
while(Source && !(isalpha(c) || '_' == c)) {
Source.get(c);
if(c == '\n') ++LineNo;
}
string aKey(1,c);
while(Source && (isalnum(c) || '_' == c)) {
Source.get(c);
if(isalnum(c) || '_' == c)
aKey += c;
}
Source.putback(c);
//if(c)
//CrossRef[aKey].push_back(LineNo);
}
time(&endtime);
cout << "time:" << endtime - starttime << '\n';
}
测试结果:
DEBUG版本:
I/O时间: 6s
hash_map版本: 10s
SGI map版本: 24s
MS map版本: 26s
RELEASE版本(加大了测试文本到20M):
I/O时间: 3s
hash_map版本: 7s
SGI map版本: 14s
MS map版本: 18s
测试结果相当稳定, 连续多次测试, 结果完全一样, 从结果看, hash_map由于其O(1)的访问时间, 完全占据了性能优势, 可惜MS没有提供hash_map用于对比测试, 不过从map的实现上看, SGI的实现也是明显优于MS实现, 快了10%~30%左右.
