Kxgx.com - 移动开发网

本站快讯:
搜索: 您的位置主页>移动开发>嵌入式开发>>阅读文章:[转贴]大家好 看看这个测试报告很有意思的哦 ^_^

[转贴]大家好 看看这个测试报告很有意思的哦 ^_^

2006-05-29   来源:   作者:   【 】 评论:0 条

转自:http://blog.csdn.net/johnlya/archive/2006/05/20/747089.aspx

BerkeleyDB和eXtremeDB性能在LINUX下的比较

 
1、BerkeleyDB测试源程序:     
 
#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
extern int getopt(int, char * const *, const char *);
#else
#include <unistd.h>
#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 elapsed time: %f seconds : %g key/data pairs per sec ",
     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 ", 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): ");
  printf(" skipped: bulk get requires a key size >= 10 ");
 }
 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] ",
     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 <platform.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <mcoHA.h>
#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[] = {
  " 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 insertion and deletion "
  "done in a separate transaction, so the commit time is included in the "
  "measurements. "
 };
 char text1[] = {
  "Copyright (c) 2001-2006 McObject LLC. All Right Reserved. "
 };
 printf("%s eXtremeDB runtime version %d.%d, build %d %s Press Enter to start",
  text, MCO_COMP_VER_MAJOR, MCO_COMP_VER_MINOR, MCO_COMP_BUILD_NUM,text1);
 getchar();
}
static void errhandler( int n ) {
 printf( " eXtremeDB 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 ");
   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( " error %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, (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) ",
  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) ",
  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) ",
  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, (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 ", (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, (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( " Press 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 <key> hkey[100000];
 voluntary tree <key> tkey;
};
3、测试结果为:无法上传请查看:http://blog.csdn.net/johnlya/archive/2006/05/20/747089.aspx)
一、BerkeleyDB:
二、eXtremeDB:
 
Tags:  
责任编辑:
  • 请文明参与讨论,禁止漫骂攻击。 用户名:新注册)密码:匿名:
    评论总数:0 [ 查看全部 ] 网友评论
    关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 帮助