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 ...
随机推荐
- C# 利用SMTP异步发送邮件
C#实现收发邮件功能需要用到两个命名空间 System.Net; 和 System.Net.Mail; SmtpClient client = new SmtpClient("smtp.g ...
- postal邮件发送(二):Email headers,附件,图片介绍
接上篇 http://www.cnblogs.com/mybky/p/5690567.html 1.邮件headers 除此之外,还有Reply-To,用于回复邮箱 2.邮件带有图片 邮件发送图片,p ...
- PhotoShop基本工具 -- 移动工具
艺术或学习的东西吧, 爱好 比学编程还难 PS版本号 : PhotoShop CS6 1. 移动工具 (1) 工具栏和属性栏 工具栏 和 属性栏 : 左側的是工具栏, 每选中一个工具, 在菜单条的 ...
- Oracle索引——位图索引
1.语法create bitmap index index_name on 表名(字段);2.举个例子你就能明白了:如有表 test(id,name,address)数据(1,张三,大连)(2,李四, ...
- 什么是PHP
PHP(PHP: Hypertext Preprocessor的缩写,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,入门门槛较低,易于学习,使用广泛, ...
- [转]Jailbreak Detection Methods
Source: http://blog.spiderlabs.com/2014/10/jailbreak-detection-methods.html Many iOS applications co ...
- 小菜的SharePoint Tips
07. 设计模式应用案例(下) 前文用C#代码实现了Facade模式.Adapter模式.Strategy模式.Bridge模式和Abstract Factory模式解决实际业务需求.本文将继续以C# ...
- AJAX异步提交,浏览器总跳出下载界面
问题: 我在写一个网页的“用户登录”部分时,要将用户名和密码传到后端验证,想在前端用了AJAX异步提交功能,将 用户名密码传到后端,然后后端返回验证结果.但AJAX写好后每次刷新网页都会跳出下载窗口, ...
- css换行和超出隐藏
一.强制换行1 word-break: break-all; 只对英文起作用,以字母作为换行依据.2 word-wrap: break-word; 只对英文起作用,以单词作为换行依据.3 white- ...
- 仿腾讯微博的一个弹出框 v0.1 beta
仿腾讯微博的一个弹出框 v0.1 beta 代码写的不太好,新手请大家海涵,只为博君一笑,勿放在心上. 写在这里留作纪念,也许以后用的到. 效果 CSS .prompt{ position: ab ...