那谁的技术博客

感兴趣领域:高性能服务器编程,存储,算法,Linux内核
随笔 - 210, 文章 - 0, 评论 - 1183, 引用 - 0
数据加载中……

commoncache与tokyocabinet插入数据的效率比较

最近tokyocabinet这个数据库很流行,网上出现很多研究这个玩意儿的文章。在它的主页上,给出的benchmark表明,在它的硬件环境下,插入一百万数据仅需不到一秒的时间。

我被震撼了,为了亲眼所见,也为了和我之前写的commoncache库进行比较,我决定在我自己的机器上,使用同样类型,大小的数据,同样的量级,进行插入数据这个操作的比较。

下面给出我写的测试文件:
针对tokyocabinet的:
test_unfix_cache.c
/********************************************************************

    created:    2008/05/30

    filename:     test_unfix_cache.c

    author:        Lichuang

                

    purpose:    

********************************************************************
*/



#include 
<stdlib.h>

#include 
<stdio.h>

#include 
<string.h>

#include 
<errno.h>

#include 
<unistd.h>

#include 
<fcntl.h>

#include 
<sys/types.h>

#include 
<sys/wait.h>

#include 
<netinet/in.h>

#include 
<signal.h>

#include 
<arpa/inet.h>



#include 
<tcutil.h>

#include 
<tchdb.h>



TCHDB 
*hdb = NULL;



void mainloop();

void createrandstring(char* stringint len);



int isparent = 0;



int main()

{

    hdb 
= tchdbnew();

    
if (!hdb)

    {

        printf(
"create error!\n");

        exit(
-1);

    }



    
if (!tchdbopen(hdb, "1.hdb", HDBOWRITER | HDBOCREAT))

    {

        printf(
"open error!\n");

        exit(
-1);

    }



    mainloop();



    
return 0;

}



#define STRING_LEN 5



void mainloop()

{

    
char string[STRING_LEN];

    
int num, i, len;



    srand((unsigned)time(NULL) 
+ getpid());

    len 
= STRING_LEN - 1;



    
for (i = 1; i < 1000000++i)

    {

        memset(
string0, STRING_LEN);

        createrandstring(
string, len);



        
if (!tchdbput2(hdb, stringstring))            

        {

        }

        
else

        {

        }

    }



    printf(
"pid = %d, test done\n", getpid());

}



const char str[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";



void createrandstring(char* stringint len)

{

    
int x, i;

    
for (i = 0; i < len - 1++i)

    {

        x 
= rand() % (sizeof(str) - 1);  

        
//x = (i + len) % (sizeof(str) - 1);  

        

        
string[i] = str[x];

    }



    
string[++i] = str[len % sizeof(str) + 1];

    
string[i] = '\0';

}


对应的Makefile:
all:test_unfix_cache.c
    gcc 
-I/usr/local/include test_unfix_cache.c -o test_unfix_cache  -L/usr/local/lib -ltokyocabinet -lz -lbz2 -lrt -lpthread -lm -lc

而针对commoncache的测试文件是:
/********************************************************************
    created:    2008/05/30
    filename:     test_unfix_cache.c
    author:        Lichuang
                
    purpose:    
********************************************************************
*/

#include 
<stdlib.h>
#include 
<stdio.h>
#include 
<string.h>
#include 
<errno.h>
#include 
<unistd.h>
#include 
<fcntl.h>
#include 
<sys/types.h>
#include 
<sys/wait.h>
#include 
<netinet/in.h>
#include 
<signal.h>
#include 
<arpa/inet.h>

#include 
"ccache.h"
#include 
"memory.h"

ccache_t
* cache;

void mainloop();
void createrandstring(char* stringint len);

int isparent = 0;

int main()
{
    cache 
= ccache_create(75000100"./testunfixmap"108101);
    
if (NULL == cache)
    {
        printf(
"create_cache error!\n");
        
return -1;
    }

    mainloop();

    
return 0;
}

#define STRING_LEN 5

int cmp_fun(const void* data1, const void* data2, int len)
{
    
return memcmp(data1, data2, sizeof(char* len);
}

void mainloop()
{
    
char string[STRING_LEN];
    
int i, len;
    ccache_data_t data;

    srand((unsigned)time(NULL) 
+ getpid());
    len 
= STRING_LEN - 1;

    
for (i = 1; i < 1000000++i)
    {
        memset(
string0, STRING_LEN);
        createrandstring(
string, len);

        data.datasize 
= len;
        data.keysize 
= len;
        data.data 
= (void*)&string;
        data.key  
= (void*)&string;

        
//printf("i = %d\n", i);

        
if (0 > ccache_insert(&data, cache, cmp_fun, NULL, NULL))
        {
        }
        
else
        {
            
continue;
        }
    }

    printf(
"pid = %d, test done\n", getpid());
}

const char str[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

void createrandstring(char* stringint len)
{
    
int x, i;
    
for (i = 0; i < len - 1++i)
    {
        x 
= rand() % (sizeof(str) - 1);  
        
//x = (i + len) % (sizeof(str) - 1);  
        
        
string[i] = str[x];
    }

    
string[++i] = str[len % sizeof(str) + 1];
    
string[i] = '\0';
}

在commoncache的项目代码的test目录中,同样存在一个名为test_unfix_test.c的文件,是我以前写commoncache时测试用的,不过原来的那个文件功能较多,不仅有插入操作,还有查找,替换等操作,这次为了测试,我对这个文件进行了精简,只保留插入数据操作的部分。使用的是commoncache中的hash-rbtree结构。

性能测试结果:
tokyocabinet:
lichuang@lichuang:/media/e/source/tokyocabinet/test$ time ./test_unfix_cache 
pid 
= 15464, test done

real    0m0.373s
user    0m0.364s
sys    0m0.008s
commoncache:
lichuang@lichuang:/media/e/source/ccache/bin$ time ./test_unfix_cache 
pid 
= 15514, test done

real    0m0.235s
user    0m0.228s
sys    0m0.004s
看上来,commoncache比之tokyocabinet还稍好一些?
不过,commoncache与tokyocabinet还是有区别的,前者工作的区域是共享内存,后者是磁盘文件,有这样的表现,确实惊人。

这次比较,起码给了我一些些的自信,我的commoncache不比世界一流的文件数据库性能差的太多。
下一步,我想继续下面的几个工作:
1) 国庆的时候,整理出一份commoncache的设计文档,算是阶段性的一个小结。另外,commoncache在插入数据的时候,有时会报错,我还得查查是为什么。
2) 抽空要开始研究文件数据库的实现了,tokyocabinet就是一个不错的参考。

另外,多说几句,一个产品要成功,仅仅有性能是不够,可维护性,可备份性,优秀的协议设计等等,都是重要的指标。我想,commoncache只做到了性能这一点,我需要在其他几方面继续努力。

哦,忘了给出我的环境参数:
ubuntu9.04,内核2.6.18,内存3G,intel 双核CPU。


posted on 2009-09-20 20:02 那谁 阅读(4208) 评论(2)  编辑 收藏 引用 所属分类: ccache

评论

# re: commoncache与tokyocabinet插入数据的效率比较  回复  更多评论   

看你的blog好久了,再不顶真说不过去了:)
2009-09-30 21:57 | nanduo

# re: commoncache与tokyocabinet插入数据的效率比较  回复  更多评论   

内存比磁盘快这么一点也算可以?
2013-10-30 01:17 | ddd

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理