您的位置:首页 > 编程语言 > C语言/C++

慎用Visual Studio C++默认的hash_map

2011-08-05 09:07 267 查看
慎用Visual Studio C++默认的hash_map

写了一个模块客户端和服务器共用,为了加快查询速度,用了hash_map,今天一个兄弟老卢测试说将其中的hash_map替换成map后速度更快,有点晕。自己写了一段代码在Windows下用Visual Studio C++测试hashmap。

首先说明,hashmap目前还没有进入C++的规范,但是大部分厂商都实现了这个容器,测试的hashmap有两种:

l Visual Studio 2003自己默认带的hash_map,

l STLport的hash_map

当然用过Visual Studio默认自带的hashmap的兄弟会知道,其和SGI的一脉的STL实现不太一样,包括模板声明方式等都自成一套。所以其实使用的时候还要注意。这儿就不啰嗦这个问题了。同时麻烦大家注意我测试的版本是2003,使用的是DEBUG版本。

测试代码如下,如果你觉得枯燥,可以跳过这段看代码直接看结果,代码其中用了ACE的一些代码测试时间差:

#include <stdio.h>
#include <iostream>
#include <map>
#include <hash_map>
#include <ace/OS.h>
#include <ace/Time_Value.h>

void test_hash_map()
{
	ACE_Time_Value tvStart(0);
	ACE_Time_Value tvEnd(0);
	ACE_Time_Value tvPassTime(0);
	tvStart = ACE_OS::gettimeofday();

	hash_map<size_t,int>   int_hash_map;
	//测试10万次
	const size_t TEST_NUMBER = 10*10000;
	//注意这行代码,VS.NET默认的STL没有这个函数的,而STLPort的实现有这个函数
	int_hash_map.resize(TEST_NUMBER);
	//顺序插入一组数据
	for (size_t i= 0;i<TEST_NUMBER;++i)
	{
		int_hash_map[i]=0;
	}
	//查询20万次,一般能查询到,一半不能查询到
	for (size_t i= 0;i<2*TEST_NUMBER;++i)
	{
		int_hash_map.find(i);
	}
	//得到毫秒的时间差
	tvEnd = ACE_OS::gettimeofday();
	tvPassTime = tvEnd - tvStart;
	cout<<"test_hash_map gettimeofday :"<<tvPassTime.msec()<<" "<<endl;
};

void test_map()
{
	ACE_Time_Value tvStart(0);
	ACE_Time_Value tvEnd(0);
	ACE_Time_Value tvPassTime(0);
	tvStart = ACE_OS::gettimeofday();
	map<size_t,int>   int_map;
	//测试10万个数据
	const size_t TEST_NUMBER = 10*10000;
	for (size_t i= 0;i<TEST_NUMBER;++i)
	{
		int_map[i]=0;
	}
	for (size_t i= 0;i<2*TEST_NUMBER;++i)
	{
		int_map.find(i);
	}
    //得到毫秒的时间差
    tvEnd = ACE_OS::gettimeofday();    tvPassTime = tvEnd - tvStart;    cout<<"test_map gettimeofday :"<<tvPassTime.msec()<<" "<<endl;};int main(int argc, char* argv[]){    for (int j=0;j<10;++j)    {        test_hash_map();        test_map();    }    return 0;}


使用Visual Studio 默认的STL的测试结果是,比较让人惊讶的是hash_map的速度不比map快多少,(在我一个同事的VS2005的机器上测试,map居然比hash_map快),节约篇幅,只写了2组测试结果。其他测试结果偏差不大。

test_hash_map gettimeofday :3093

test_map gettimeofday :3484

test_hash_map gettimeofday :3250

test_map gettimeofday :3531

而使用STLPort的测试结果如下:hash_map速度比MS的实现快了一倍多,map也比MS的实现快。

test_hash_map gettimeofday :1312

test_map gettimeofday :2359

test_hash_map gettimeofday :1312

test_map gettimeofday :2375

而由于MS的hash_map实现没有resize函数,我单独对STLport的实现测试了先使用resize函数的结果如下,大家可以发现如果先使用resize函数,速度可以得到更大的提高。

test_hash_map gettimeofday :1015

test_map gettimeofday :2343

test_hash_map gettimeofday :1031

test_map gettimeofday :2375



我对STLport的hash_map的实现比较熟悉,应该就是hash因子的数组加List存放数据。而MS Visual Studio的实现我初步浏览了一下,应该也类似,具体原因就说不清了,我也不太想耗费体能找出问题的症结所在,就只看表面现象吧。

所以大家在使用Visual Studio 的hash_map的时候要当心了,

l 第一,这个hash_map实现不怎么快,

l 第二,微软的实现不地道,,基本可以肯定SGI的实现会是默认的标准,有兴趣可以看看BOOST的unordered_map,未来的hash_map应该就是这个样子。

l 第三,没有resize函数,这样几乎可以肯定,这个实现的大容量时的表现应该很烂。我的同事测试在2005下测试上面的程序,测试数量改为了100万后,他的说法是他最后没有耐心等待结果了。而我用2003的STLport测试结果是10s多完成测试。为什么我敢肯定,建议大家去看看hash_map的实现。

另外inmore看了我的测试结果说好像MS实现的迭代器遍历要快,我测试了一下,发现果真如此,难道微软的工程师昏了头,优化hash_map的迭代器遍历去了,但多少怀疑这和MS实现还是有一定得关系。

Microsoft的自己的编译器,实现的东西居然比别人慢一个数量级,MS的工程师应该羞愧一个。测试限于2003和2005,没有涉及2008,但我基本也不抱太大希望。当然,我在这儿也不劝你把所有的东西替换为STLport的实现,为啥呢?如果你用的第三方库很多,这个成本过高了。除非你和我一样,是一个在Windows下调试服务器代码的异类。

/article/2092874.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: