[转贴]大家看看这个测试报告~~挺有意思

转自: [url]http://blog.csdn.net/johnlya/archive/2006/05/20/747089.aspx[/url] BerkeleyDB和eXtremeDB性能在LINUX下的比较 1、BerkeleyDB测试源程序: #include #include #include #include #include #ifdef _WIN32 extern int getopt(int, char * const *, const char *); #else #include #endif #include "db.h" extern void __os_clock __P((DB_ENV *, u_int32_t *, u_int32_t *)); void usage __P((void)); struct db_time { u_int32_t secs, usecs; }; struct db_time start_time, end_time; u_int32_t pagesize = 32 * 1024; u_int bulkbufsize = 4 * 1024 * 1024; u_int logbufsize = 8 * 1024 * 1024; u_int cachesize = 32 * 1024 * 1024; u_int datasize = 32; u_int keysize = 8; u_int numitems = 0; FILE *fp; char *progname; void op_ds(u_int, int); void op_ds_bulk(u_int, u_int *); void op_tds(u_int, int, u_int32_t); void res(char *, u_int); void res(char *msg, u_int ops) { double elapsed; struct db_time v; v.secs = end_time.secs - start_time.secs; v.usecs = end_time.usecs - start_time.usecs; if (start_time.usecs > end_time.usecs) { v.secs--; v.usecs += 1000000; } elapsed = v.secs + v.usecs / 1e6; printf("%s\n\telapsed time: %f seconds : %g key/data pairs per sec\n", msg, elapsed, ops / elapsed); } void op_ds(u_int ops, int update) { char *letters = "abcdefghijklmnopqrstuvwxuz"; DB *dbp; DBT key, data; char *keybuf, *databuf; DB_MPOOL_STAT *gsp; (void)remove("a"); assert((keybuf = malloc(keysize)) != NULL); assert((databuf = malloc(datasize)) != NULL); memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = keybuf; key.size = keysize; memset(keybuf, 'a', keysize); data.data = databuf; data.size = datasize; memset(databuf, 'b', datasize); assert(db_create(&dbp, NULL, 0) == 0); dbp->set_errfile(dbp, stderr); assert(dbp->set_pagesize(dbp, pagesize) == 0); assert(dbp->open(dbp, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0666) == 0); dbp->dbenv->memp_stat(dbp->dbenv, &gsp, NULL, DB_STAT_CLEAR); if (update) { __os_clock(NULL, &start_time.secs, &start_time.usecs); for (; ops > 0; --ops) { keybuf[(ops % keysize)] = letters[(ops % 26)]; assert(dbp->put(dbp, NULL, &key, &data, 0) == 0); } __os_clock(NULL, &end_time.secs, &end_time.usecs); } else { assert(dbp->put(dbp, NULL, &key, &data, 0) == 0); __os_clock(NULL, &start_time.secs, &start_time.usecs); for (; ops > 0; --ops) assert(dbp->get(dbp, NULL, &key, &data, 0) == 0); __os_clock(NULL, &end_time.secs, &end_time.usecs); } dbp->dbenv->memp_stat(dbp->dbenv, &gsp, NULL, 0); assert(gsp->st_cache_miss == 0); assert(dbp->close(dbp, 0) == 0); } void op_ds_bulk(u_int ops, u_int *totalp) { DB *dbp; DBC *dbc; DBT key, data; u_int32_t len, klen; u_int i, total; char *keybuf, *databuf; void *pointer, *dp, *kp; DB_MPOOL_STAT *gsp; (void)remove("a"); assert((keybuf = malloc(keysize)) != NULL); assert((databuf = malloc(bulkbufsize)) != NULL); memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = keybuf; key.size = keysize; data.data = databuf; data.size = datasize; memset(databuf, 'b', datasize); assert(db_create(&dbp, NULL, 0) == 0); dbp->set_errfile(dbp, stderr); assert(dbp->set_pagesize(dbp, pagesize) == 0); assert(dbp->set_cachesize(dbp, 0, cachesize, 1) == 0); assert(dbp->open(dbp, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0666) == 0); for (i = 1; i <= numitems; ++i) { (void)sprintf(keybuf, "%10d", i); assert(dbp->put(dbp, NULL, &key, &data, 0) == 0); } #if 0 fp = fopen("before", "w"); dbp->set_msgfile(dbp, fp); assert (dbp->stat_print(dbp, DB_STAT_ALL) == 0); #endif assert(dbp->cursor(dbp, NULL, &dbc, 0) == 0); data.ulen = bulkbufsize; data.flags = DB_DBT_USERMEM; dbp->dbenv->memp_stat(dbp->dbenv, &gsp, NULL, DB_STAT_CLEAR); if (ops > 10000) ops = 10000; __os_clock(NULL, &start_time.secs, &start_time.usecs); for (total = 0; ops > 0; --ops) { assert(dbc->c_get( dbc, &key, &data, DB_FIRST | DB_MULTIPLE_KEY) == 0); DB_MULTIPLE_INIT(pointer, &data); while (pointer != NULL) { DB_MULTIPLE_KEY_NEXT(pointer, &data, kp, klen, dp, len); if (kp != NULL) ++total; } } __os_clock(NULL, &end_time.secs, &end_time.usecs); *totalp = total; dbp->dbenv->memp_stat(dbp->dbenv, &gsp, NULL, 0); assert(gsp->st_cache_miss == 0); #if 0 fp = fopen("before", "w"); dbp->set_msgfile(dbp, fp); assert (dbp->stat_print(dbp, DB_STAT_ALL) == 0); #endif /*assert(dbp->close(dbp, 0) == 0);*/ } void op_tds(u_int ops, int update, u_int32_t txn_flags) { DB *dbp; DBT key, data; DB_ENV *dbenv; DB_TXN *txn; char *keybuf, *databuf; DB_MPOOL_STAT *gsp; #ifndef _WIN32 (void)system("rm -rf TESTDIR; mkdir TESTDIR"); #endif assert((keybuf = malloc(keysize)) != NULL); assert((databuf = malloc(datasize)) != NULL); memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = keybuf; key.size = keysize; memset(keybuf, 'a', keysize); data.data = databuf; data.size = datasize; memset(databuf, 'b', datasize); assert(db_env_create(&dbenv, 0) == 0); dbenv->set_errfile(dbenv, stderr); assert(dbenv->set_flags(dbenv, DB_AUTO_COMMIT | txn_flags, 1) == 0); assert(dbenv->set_lg_bsize(dbenv, logbufsize) == 0); assert(dbenv->open(dbenv, "TESTDIR", DB_CREATE | DB_PRIVATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0666) == 0); assert(db_create(&dbp, dbenv, 0) == 0); assert(dbp->set_pagesize(dbp, pagesize) == 0); assert(dbp->open(dbp, NULL, "a", NULL, DB_BTREE, DB_CREATE, 0666) == 0); if (update) { dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR); __os_clock(NULL, &start_time.secs, &start_time.usecs); for (; ops > 0; --ops){ assert(dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0); assert(dbp->put(dbp, NULL, &key, &data, 0) == 0); assert(txn->commit(txn, 0) == 0); } __os_clock(NULL, &end_time.secs, &end_time.usecs); dbenv->memp_stat(dbenv, &gsp, NULL, 0); assert(gsp->st_page_out == 0); } else { assert(dbp->put(dbp, NULL, &key, &data, 0) == 0); dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR); __os_clock(NULL, &start_time.secs, &start_time.usecs); for (; ops > 0; --ops) { assert(dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0); assert(dbp->get(dbp, NULL, &key, &data, 0) == 0); assert(txn->commit(txn, 0) == 0); } __os_clock(NULL, &end_time.secs, &end_time.usecs); dbenv->memp_stat(dbenv, &gsp, NULL, 0); assert(gsp->st_cache_miss == 0); } assert(dbp->close(dbp, 0) == 0); assert(dbenv->close(dbenv, 0) == 0); } int main(int argc, char *argv[]) { extern char *optarg; extern int optind; u_int ops, total; int ch; int major, minor, patch; if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; else ++progname; ops = 100000; while ((ch = getopt(argc, argv, "d:k:o:p:")) != EOF) switch (ch) { case 'd': datasize = (u_int)atoi(optarg); break; case 'k': keysize = (u_int)atoi(optarg); break; case 'o': ops = (u_int)atoi(optarg); break; case 'p': pagesize = (u_int32_t)atoi(optarg); break; case '?': default: usage(); } argc -= optind; argv += optind; numitems = (cachesize / (keysize + datasize - 1)) / 2; db_version(&major, &minor, &patch); printf("Using Berkeley DB %d.%d.%d - ", major, minor, patch); printf("ops: %u; keysize: %d; datasize: %d\n", ops, keysize, datasize); op_ds(ops, 0); res("DS (read):", ops); if (keysize >= 8) { op_ds_bulk(ops, &total); res("DS (bulk read):", total); } else { printf("DS (bulk read):\n"); printf("\tskipped: bulk get requires a key size >= 10\n"); } op_ds(ops, 1); res("DS (write):", ops); op_tds(ops, 0, 0); res("TDS (read):", ops); op_tds(ops, 1, DB_LOG_INMEMORY); res("TDS (write, in-memory logging):", ops); op_tds(ops, 1, DB_TXN_NOSYNC); res("TDS (write, no-sync on commit):", ops); op_tds(ops, 1, DB_TXN_WRITE_NOSYNC); res("TDS (write, write-no-sync on commit):", ops); op_tds(ops, 1, 0); res("TDS (write, sync on commit):", ops); return (EXIT_SUCCESS); } void usage() { fprintf(stderr, "usage: %s [-d datasize] [-k keysize] [-o ops] [-p pagesize]\n", progname); exit(1); } 2、eXtremeDB测试源程序: /***************************************************************** * * * Copyright (c) 2001-2006 McObject LLC. All Right Reserved. * * * *****************************************************************/ /* This test allows to receive some results about the eXtremeDB performance * for all basic operations. This test inserts N objects into a class, creating * a hash index as it does insertions; then separatelly builds a tree index, * performs searches using a tree and a hash table, an a sequential search. * At last the tree is removed and all the object are deleted one-by-one. * Each Insetrtion and deletion done in a separate transaction, so the * commit time is included in the measurements. */ #include #include #include #include //#include #include "perf2.h" /* Make sure you've got this 16M, otherwise you'll be measuring * the performance of your disk. */ #define DBSIZE ( 1024 * 16000 ) #define PAGESIZE 128 const int MAP_ADDRESS = 0x20000000; /* If you change the number of objects inserted, make sure that you * first have enough memory (DBSIZE), and also decalred hash table * size appropriatelly (hkey[estimated_numeber_of_entries] in perf2.mco */ const int nRecords = 100000; void _SH_(void) { char text[] = { "\nThis test allows to receive some results about the eXtremeDB\n" "performance for all basic operations. This test inserts N objects\n" "into a class, creating a hash index as it does insertions; then\n" "separatelly builds a tree index,performs searches using a tree and\n" "a hash table, an a sequential search.At last the tree is removed\n" "and all the object are deleted one-by-one. Each insertion and deletion\n" "done in a separate transaction, so the commit time is included in the\n" "measurements.\n" }; char text1[] = { "Copyright (c) 2001-2006 McObject LLC. All Right Reserved.\n\n" }; printf("%s\neXtremeDB runtime version %d.%d, build %d\n%s\n\nPress Enter to start", text, MCO_COMP_VER_MAJOR, MCO_COMP_VER_MINOR, MCO_COMP_BUILD_NUM,text1); getchar(); } static void errhandler( int n ) { printf( "\neXtremeDB runtime fatal error: %d", n ); getchar(); exit( -1 ); } int main( void ) { const char *dbName = "perf2"; time_t start_time; MCO_RET rc; mco_db_h db = 0; mco_trans_h t; int i; long n = 0; Record rec; mco_cursor_t c; uint4 key = 1999; void *start_mem; mco_runtime_info_t info; _SH_(); mco_get_runtime_info( &info); if ( info.mco_shm_supported ) { start_mem = (void*)MAP_ADDRESS; } else { start_mem = (void*)malloc(DBSIZE); if (!start_mem) { printf("Couldn't allocated memory\n"); exit (1); } }; mco_error_set_handler( &errhandler ); rc= mco_runtime_start(); rc = mco_db_open( dbName, perf2_get_dictionary(), start_mem, DBSIZE, (uint2) PAGESIZE ); if ( rc ) { printf( "\nerror %d creating database", rc ); if ( !info.mco_shm_supported ) free( start_mem ); exit( 1); } /* connect to the database, obtain a database handle */ mco_db_connect( dbName, &db ); /* insert Records, don't create the tree index yet */ printf("Insert "); Sleep(20); start_time = msec(); for (i=0; i < nRecords; i++) { key = (3141592621u*i + 2718281829u) % 1000000007u; rc = mco_trans_start( db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t ); if( MCO_S_OK != rc ) exit(1); rc = Record_new(t, &rec); Record_key_put(&rec, key); rc = mco_trans_commit(t); if (!rc ) n++; if (i%(nRecords/10)==0) printf ("."); } printf(" %d objects: %d milliseconds,(%d microsecs/object)\n", n, (int)(msec() - start_time), ((msec() - start_time) * 1000)/n); /* create the tree index */ Sleep(20); rc = mco_trans_start( db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t ); if( MCO_S_OK != rc ) { if ( !info.mco_shm_supported ) free( start_mem ); exit(1); }; printf("Creating tree ...... "); start_time = msec(); Record_tkey_create (t); mco_trans_commit(t); printf(" %d objects: %d milliseconds (%d microsecs/object)\n", nRecords, (int)(msec() - start_time ), ((msec() - start_time) * 1000)/nRecords); /* hash search */ Sleep(20); rc = mco_trans_start( db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &t ); if( MCO_S_OK != rc ) { if ( !info.mco_shm_supported ) free( start_mem ); exit(1); }; printf("Hash search "); start_time = msec(); for (i=0; i < nRecords; i++) { key = (3141592621u*i + 2718281829u) % 1000000007u; rc = Record_hkey_find(t, key, &rec); if (i%(nRecords/10)==0) printf ("."); } printf("% d searches: %d milliseconds (%d microsecs/search)\n", nRecords, (int)(msec() - start_time ), ((msec() - start_time) * 1000)/nRecords); mco_trans_commit(t); /* tree search */ Sleep(20); printf("Tree search "); start_time = msec(); rc = mco_trans_start( db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &t ); Record_tkey_index_cursor(t, &c ); for (i=0; i < nRecords; i++) { key = (3141592621u*i + 2718281829u) % 1000000007u; Record_tkey_search( t, &c, MCO_EQ, key ); if (i%(nRecords/10)==0) printf ("."); } printf(" %d searches: %d milliseconds (%d microsecs/search)\n", nRecords, (int)(msec() - start_time ), ((msec() - start_time) * 1000)/nRecords); mco_trans_commit(t); /* cursor movements */ Sleep(20); printf("Sequential "); start_time=msec(); rc = mco_trans_start( db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &t ); Record_tkey_index_cursor(t, &c ); for (n = 0,rc = mco_cursor_first(t, &c); rc == MCO_S_OK; rc = mco_cursor_next(t, &c)) { if (n%(nRecords/10)==0) printf ("."); n++; } printf(" %d searches: %d milliseconds (%d microsecs/search)\n", n, (int)(msec() - start_time ), ((msec() - start_time) * 1000)/n); mco_trans_commit(t); /* removing the tree */ rc = mco_trans_start( db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t ); if( MCO_S_OK != rc ) { if ( !info.mco_shm_supported ) free( start_mem ); exit(1); }; printf("Removing the tree ...... "); start_time = msec(); Record_tkey_drop (t); mco_trans_commit(t); printf(" %d milliseconds\n", (int)(msec() - start_time )); /* Search using hash index and remove the object ones found */ printf("Search/delete "); start_time = msec(); for (n=0,i=0; i < nRecords; i++) { key = (3141592621u*i + 2718281829u) % 1000000007u; rc = mco_trans_start( db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t ); if( MCO_S_OK != rc ) exit(1); rc = Record_hkey_find(t, key, &rec); rc = Record_delete(&rec); rc = mco_trans_commit(t); if (!rc) n++; if (n%(nRecords/10)==0) printf ("."); } printf(" %d objects: %d milliseconds (%d microsecs/object)\n", n, (int)(msec() - start_time ), ((msec() - start_time) * 1000)/n); /* disconnect from the database, db is no longer valid */ mco_db_disconnect( db ); /* destroy the database */ mco_db_close( dbName ); mco_runtime_stop(); if ( !info.mco_shm_supported ) free( start_mem ); printf( "\nPress Enter to exit" ); getchar(); PROG_EXIT(0); } 其数据库为: /***************************************************************** * * * Copyright (c) 2001-2006 McObject LLC. All Right Reserved. * * * *****************************************************************/ #define int1 signed<1> #define int2 signed<2> #define int4 signed<4> #define uint8 unsigned<8> #define uint4 unsigned<4> #define uint2 unsigned<2> #define uint1 unsigned<1> declare database perf2; class Record { uint4 key; hash hkey[100000]; voluntary tree tkey; }; 3、测试结果为:(参照http://blog.csdn.net/johnlya/archive/2006/05/20/747089.aspx) 一、BerkeleyDB: 二、eXtremeDB: