最近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* string, int 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(string, 0, STRING_LEN);
createrandstring(string, len);
if (!tchdbput2(hdb, string, string))
{
}
else
{
}
}
printf("pid = %d, test done\n", getpid());
}
const char str[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
void createrandstring(char* string, int 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* string, int len);
int isparent = 0;
int main()
{
cache = ccache_create(75000, 100, "./testunfixmap", 10, 810, 1);
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(string, 0, 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* string, int 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。