C++ unordered_map 在key为string类型和char*类型时测试时间性能差异
测试系统liunx centos6.5
代码如下
#include <string.h>
#include <sstream>
#include <list>
#include <sys/time.h>
#include <unordered_map>
#include <cstdlib>
#include <stdio.h>
#include "unistd.h" using namespace std; struct Cmp {
bool operator()(const char* a,const char* b) const {
return memcmp(a,b,64)==0;
}
}; struct hash_func {
int operator()(const char* str) const {
int seed = 131;
int hash = 0;
hash = (hash * seed) + (*str);
while(*(++str)) {
hash = (hash * seed) + (*str);
} return hash & (0x7FFFFFFF);
}
}; double current_usec(){
struct timeval tv;
gettimeofday( &tv, NULL );
return tv.tv_sec * 1000 * 1000 + tv.tv_usec;
} //产生随机串
char* genRandomString(int length){
sleep(1);
int flag, i;
char* string;
srand((unsigned) time(NULL));
if ((string = (char*) malloc(length)) == NULL ) {
printf("Malloc failed!flag:14\n");
return NULL ;
} for (i = 0; i < length - 1; i++)
{
flag = rand() % 3;
switch (flag)
{
case 0:
string[i] = 'A' + rand() % 26;
break;
case 1:
string[i] = 'a' + rand() % 26;
break;
case 2:
string[i] = '0' + rand() % 10;
break;
default:
string[i] = 'x';
break;
}
} string[length - 1] = '\0';
return string;
} int main(int argc, char* argv[] ){
char* value;
string s;
std::unordered_map<const char*, int, hash_func, Cmp> mapchar;
std::unordered_map<const char*, int, hash_func, Cmp>::iterator itchar;
std::unordered_map<std::string, int> mapstring;
std::unordered_map<std::string, int>::iterator itstring; int count = atoi(argv[1]);
if(count == 0) {
printf("the count is zero");
return 0;
} std::string str[30000];
char* val[30000];
double start=0;
double end = 0; int i=0;
int num = count;
char v[64];
while(num) {
value = genRandomString(64);
strcpy(v,value);
val[i] = value;
s = value;
str[i++] = s;
--num;
} //插入count 个string
start = current_usec();
for(int i=0; i< count;++i) {
mapstring[str[i]]= rand();
}
end = current_usec();
double string_insert_us = end - start; //插入count 个char*
start = current_usec();
for(int i=0; i< count;++i) {
mapchar[val[i]]= rand();
}
end = current_usec();
double char_insert_us = end - start; //查找count 个string
start = current_usec();
for(int i=0; i<count; ++i) {
itstring = mapstring.find(str[i]);
if( itstring == mapstring.end()) {
printf("string not find,something wrong with it");
}
}
end = current_usec();
double string_find_us = end - start; //查找count个char*
start = current_usec();
for(int i=0; i<count; ++i) {
itchar = mapchar.find(val[i]);
if( itchar == mapchar.end()) {
printf("char not find,something wrong with it");
}
}
end = current_usec();
double char_find_us = end - start; //删除count 个string
start = current_usec();
for(int i=0; i<count; ++i) {
mapstring.erase(str[i]);
}
end = current_usec();
double string_del_us = end - start; //删除count 个char*
start = current_usec();
for(int i=0; i<count; ++i) {
mapchar.erase(val[i]);
}
end = current_usec();
double char_del_us = end - start; printf("插入string time is %f us \n", string_insert_us/count);
printf("插入char time is %f us\n", char_insert_us/count);
printf("查找string time is %f us\n", string_find_us/count);
printf("查找char time is %f us\n", char_find_us/count);
printf("删除string time is %f us\n", string_del_us/count);
printf("删除char time is %f us\n", char_del_us/count); return 0;
}
插入的字符串是64位的字符串,
在并发1个情况下
在并发10的情况下
并发1000
并发5000
并发10000
一开始我以为char* 的速度会快,因为插入string的时候是要构造string申请内存的,可能是我的hash函数比系统的要慢了,但是没想到会是这个结果,有相关经验的朋友可以看下是不是我写的代码有问题或者是什么情况导致的这个情况。
把hash函数修改成inline处理一下,并且加了一个map函数key为char*的进行对比
源码
#include <string.h>
#include <sstream>
#include <list>
#include <sys/time.h>
#include <unordered_map>
#include <cstdlib>
#include <stdio.h>
#include "unistd.h"
#include <map> using namespace std; struct Cmp {
inline bool operator()(const char* a,const char* b) const {
return memcmp(a,b,)==;
}
}; struct Cmp2 {
bool operator()(const char* a,const char* b) const {
return memcmp(a,b,)<;
}
}; struct hash_func {
int operator()(const char* str) const {
int seed = ;
int hash = ;
hash = (hash * seed) + (*str);
while(*(++str)) {
hash = (hash * seed) + (*str);
} return hash & (0x7FFFFFFF);
}
}; double current_usec(){
struct timeval tv;
gettimeofday( &tv, NULL );
return tv.tv_sec * * + tv.tv_usec;
} //产生随机串
char* genRandomString(int length){
sleep();
int flag, i;
char* string;
srand((unsigned) time(NULL));
if ((string = (char*) malloc(length)) == NULL ) {
printf("Malloc failed!flag:14\n");
return NULL ;
} for (i = ; i < length - ; i++)
{
flag = rand() % ;
switch (flag)
{
case :
string[i] = 'A' + rand() % ;
break;
case :
string[i] = 'a' + rand() % ;
break;
case :
string[i] = '' + rand() % ;
break;
default:
string[i] = 'x';
break;
}
} string[length - ] = '\0';
return string;
} int main(int argc, char* argv[] ){
char* value;
string s;
std::unordered_map<const char*, int, hash_func, Cmp> mapchar;
std::unordered_map<const char*, int, hash_func, Cmp>::iterator itchar;
map<const char*, int, Cmp2> mchar;
map<const char*, int, Cmp2>::iterator mitchar;
std::unordered_map<std::string, int> mapstring;
std::unordered_map<std::string, int>::iterator itstring; int count = atoi(argv[]);
if(count == ) {
printf("the count is zero");
return ;
} std::string str[];
char* val[];
double start=;
double end = ; int i=;
int num = count;
char v[];
while(num) {
value = genRandomString();
strcpy(v,value);
val[i] = value;
s = value;
str[i++] = s;
--num;
} //插入count 个string
start = current_usec();
for(int i=; i< count;++i) {
mapstring[str[i]]= rand();
}
end = current_usec();
double string_insert_us = end - start; //插入count 个char*
start = current_usec();
for(int i=; i< count;++i) {
mapchar[val[i]]= rand();
}
end = current_usec();
double char_insert_us = end - start; //插入count char*到map里面
start = current_usec();
for(int i=; i< count;++i) {
mchar[val[i]]= rand();
}
end = current_usec();
double mchar_insert_us = end - start; //查找count 个string
start = current_usec();
for(int i=; i<count; ++i) {
itstring = mapstring.find(str[i]);
if( itstring == mapstring.end()) {
printf("string not find,something wrong with it");
}
}
end = current_usec();
double string_find_us = end - start; //查找count个char*
start = current_usec();
for(int i=; i<count; ++i) {
itchar = mapchar.find(val[i]);
if( itchar == mapchar.end()) {
printf("char not find,something wrong with it");
}
}
end = current_usec();
double char_find_us = end - start; //查找count个 map char*
start = current_usec();
for(int i=; i<count; ++i) {
mitchar = mchar.find(val[i]);
if( mitchar == mchar.end()) {
printf("map char not find,something wrong with it");
}
}
end = current_usec();
double mchar_find_us = end - start; //删除count 个string
start = current_usec();
for(int i=; i<count; ++i) {
mapstring.erase(str[i]);
}
end = current_usec();
double string_del_us = end - start; //删除count 个char*
start = current_usec();
for(int i=; i<count; ++i) {
mapchar.erase(val[i]);
}
end = current_usec();
double char_del_us = end - start; //删除count个char*
start = current_usec();
for(int i=; i<count; ++i) {
mchar.erase(val[i]);
}
end = current_usec();
double mchar_del_us = end - start; printf("插入string time is %f us \n", string_insert_us/count);
printf("插入char time is %f us\n", char_insert_us/count);
printf("插入map char time is %f us\n", mchar_insert_us/count);
printf("查找string time is %f us\n", string_find_us/count);
printf("查找char time is %f us\n", char_find_us/count);
printf("查找map char time is %f us\n", mchar_find_us/count);
printf("删除string time is %f us\n", string_del_us/count);
printf("删除char time is %f us\n", char_del_us/count);
printf("删除map char time is %f us\n", mchar_del_us/count); return ;
}
并发为1
并发1000
并发10000
主要原因我猜我的hash函数自己定义的比较费时间了,需要再仔细的考虑一下看下如何能进一步的省去这个时间
C++ unordered_map 在key为string类型和char*类型时测试时间性能差异的更多相关文章
- string类型和int类型之间的转换
一.string转int 1. 使用string流 /* 字符串转整型 */ /* * istringstream:从 string 读取数据 * ostringstream:向 string 写入数 ...
- Redis 笔记与总结2 String 类型和 Hash 类型
Linux 版本信息: cat /etc/issue 或cat /etc/redhat-release(Linux查看版本当前操作系统发行版信息) CentOS release 6.6 (Final) ...
- 02_NoSQL数据库之Redis数据库:string类型和hash类型
Strings类型及操作 String是最简单的类型,一个key对应一个Value,String类型是二进制安全的.Redis的String可以包含任何数据,比如jpg图片或者序列化的对象. S ...
- 第一节: Redis之String类型和Hash类型的介绍和案例应用
一. String类型基础 1.类型介绍 典型的Key-Value集合,如果要存实体,需要序列化成字符串,获取的时候需要反序列化一下. 2. 指令Api说明 3.常用Api说明 (1).StringS ...
- C# string类型和byte[]类型相互转换
string类型转成byte[]: byte[] byteArray = System.Text.Encoding.Default.GetBytes ( str ); byte[]转成string: ...
- 关于 实体类中 时间字段 为string 类型和 datatime类型 比较
经发现, 数据库中保存时间格式数据 可以正常 排序, 数据中保存时间格式字符串 排序出现问题 /// <summary> /// 修改时间 /// </summary> pu ...
- int类型和char类型的区别
下面三个定义式的区别: int i = 1; char i = 1; char i = '1'; int用来定义整型变量,char用来定义字符型变量,要清楚的知道三个定义式的区别,可以比较它们在内存中 ...
- AngularJs:String类型和JSON相互转换
最近一周做了一个页面,制作的过程中遇到各种问题,从中可以看出本人的js基础还不够扎实,angularjs也只是刚入门的水平,现在将制作过程中遇到的问题一一汇总,方便以后查阅. 一.String类型和J ...
- Date类型和Long类型的相互转换
Date类型和Long类型的相互转换: import java.text.SimpleDateFormat; import java.util.Date; public class T { publi ...
随机推荐
- JavaScript中JSON字符串和JSON对象相互转化
JSON字符串转化为JSON对象的2种方式 一.使用函数eval var personsstr = '[{"Name":"zhangsan","Age ...
- Android中怎么去除标题栏详解
怎么出去标题栏,我再另一个博客中亦有实例在这里再详细的解释一下,也让自己能更加巩固最简单也是小重要的东西. 这里有两种方法是比较好的... 第一种: 首先,在values中建一个theme.xml 代 ...
- wcf消息模式(随记)
----------------------------------------------消息模式:1.request\reply(默认)2.one-way(单工)[Isoneway=true]客户 ...
- IP数据报是如何在网络中转发的?
首先发送方抽取目的站的网络前缀,来判断是否目的站是否位于同一网络上,如果在二者有相同的网络前缀,则,直接使用直接交付的方式, 否则,使用由路由器互连的间接交付,这要借助IP路由表,采用表驱动法,路由表 ...
- linux网卡驱动安装及锐捷使用
原创博文,转载请注明出处 先吐槽一下,以前装了个Centos win7双系统, 然后手贱一不小心把启动文件给删了,接下来就用grub恢复启动文件,整了一天也没搞出来还把win7的Boot Manage ...
- 【Apache ZooKeeper】命令行zkCli.sh使用指南
ZooKeeper命令行 原文 http://blog.csdn.net/ganglia/article/details/11606807 ZooKeeper客户端 ...
- 使用反射机制实现jQuery调用ashx类中的指定方法
使用反射机制实现jQuery调用ashx类中的指定方法 近期用asp.net做个小网站,但又不喜欢使用asp.net的服务器端控件,经过一番思量后确定前端采用原始的html.后台采用Linq to ...
- cocos2d(CCSprite绑定不规则刚体与精灵一起移动)
对于不规则的精灵我们可以借助PhysicsEditor来制作shape , 对于地图可以使用Tiled软件制作瓷砖地图. 今天主要记录一下如何把CCSprite与不规则刚体进行绑定,然后一起移动 // ...
- GCD与多线程
GCD与多线程 GCD,全称Grand Central Dispath,是苹果开发的一种支持并行操作的机制.它的主要部件是一个FIFO队列和一个线程池,前者用来添加任务,后者用来执行任务. GCD中的 ...
- Ajax实现天气预报功能
实现天气预报功能 闲来无聊,写下此文 经常看见很多网站上有那种天气预报功能,自己之前也写过一个,不过属于那种涉及WCF服务引用那种,今天发现一个更为简单的方式来实现,使用Javascript和Ajax ...