测试环境简单说明

Windows下测试

硬件环境如下:

处理器:Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz

内 存:8GB

硬 盘:希捷 ST1000DM003

操作系统:Windows 10 企业版

编译说明:

两个都是使用VS2015编译的64位Release版本。运行时库采用动态多线程版本(MD)

Linux下测试

硬件环境如下:

处理器:Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz

内 存:8GB

硬 盘:金士顿64G SSD

操作系统:ArchLinux (Linux version 4.8.13-1-ARCH)

编译说明:

两个都是使用Gcc 6.2.1编译的x64版本,使用-O2参数优化。

测试结果

LevelDBForestDB进行简单的性能测试。

两个都在单线程下进行10000次的增删查改测试,共测试5次。(这里测试的次数有点少,应该测试十万次以上的)

测试的时候可以发现(设置断点),Forest每次操作都将数据缓存在内存了,内存占用比较大。而LevelDB在添加的时候并没有缓存,但是在数据获取和修改的时候内存会变大。

总体上LevelDB占用内存小一点,但是linux下速度不及ForestDB(非常接近)。易用程度上,LevelB简单得多。磁盘占用的情况的话,Forest对磁盘使用比较少,这10000条数据占了13MB左右,而LevelDB则占了120MB左右。

Windows下测试结果

测试结果平均值对比直方图:

LevelDB 测试结果截图

ForestDB 测试结果截图

Linux下测试结果

测试结果平均值对比直方图:

LevelDB 测试结果截图

ForestDB 测试结果截图

测试代码

LevelDB测试代码

#include <cassert>
#include <string>
#include <iostream>
#include <chrono> #include "leveldb/db.h" #define TEST_FREQUENCY (10000) char* randomstr()
{
static char buf[1024];
int len = rand() % 768 + 255;
for (int i = 0; i < len; ++i) {
buf[i] = 'A' + rand() % 26;
}
buf[len] = '\0';
return buf;
} int main()
{
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true; // 打开数据库
leveldb::Status status = leveldb::DB::Open(options, "./testdb", &db);
assert(status.ok()); srand(2017);
std::string k[TEST_FREQUENCY];
for (int i = 0; i < TEST_FREQUENCY; ++i) {
k[i] = (randomstr());
}
std::string v("壹贰叁肆伍陆柒捌玖拾");
v.append(v).append(v).append(v).append(v).append(v); // 测试添加
{
auto start = std::chrono::system_clock::now();
for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = db->Put(leveldb::WriteOptions(), k[i], v);
assert(status.ok());
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << TEST_FREQUENCY <<"次添加耗时: "
<< double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
<< "秒" << std::endl;
}
// 测试获取
{
auto start = std::chrono::system_clock::now();
std::string v2[TEST_FREQUENCY];
for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = db->Get(leveldb::ReadOptions(), k[i], &v2[i]);
assert(status.ok());
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << TEST_FREQUENCY <<"次获取耗时: "
<< double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
<< "秒" << std::endl;
// 验证获取结果是否正确
std::string ss;
for (int i = 0; i < TEST_FREQUENCY; ++i) {
if (v2[i] != v) {
std::cout << "第 " << i << " 个结果不正确" << std::endl;
std::cout << v2[i] << std::endl;
}
}
}
// 测试修改
{
auto start = std::chrono::system_clock::now();
v.append(v);
for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = db->Put(leveldb::WriteOptions(), k[i], v);
assert(status.ok());
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << TEST_FREQUENCY <<"次修改耗时: "
<< double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
<< "秒" << std::endl;
} // 测试删除
{
auto start = std::chrono::system_clock::now();
for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = db->Delete(leveldb::WriteOptions(), k[i]);
assert(status.ok());
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << TEST_FREQUENCY <<"次删除耗时: "
<< double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
<< "秒" << std::endl;
}
delete db;
return 0;
}

Forest 测试代码

#include <cassert>
#include <string>
#include <iostream>
#include <chrono> #include "libforestdb/forestdb.h" #define TEST_FREQUENCY (10000) char* randomstr()
{
static char buf[1024];
int len = rand() % 768 + 255;
for (int i = 0; i < len; ++i) {
buf[i] = 'A' + rand() % 26;
}
buf[len] = '\0';
return buf;
} int main()
{
fdb_file_handle* fdbFileHandle = nullptr;
fdb_kvs_handle* fdbKvsHandle = nullptr;
fdb_status status; // 初始化ForestDB
// 1、文件配置设置配置
fdb_config fileConfig = fdb_get_default_config();
{// WAL阈值4K
fileConfig.wal_threshold = 4096;
// 缓存大小64MB
fileConfig.buffercache_size = 64 * 1024 * 1024;
// 设置使用默认的kvs
fileConfig.multi_kv_instances = false;
// 关闭循环块复用
fileConfig.block_reusing_threshold = 100;
// 使用序列树
fileConfig.seqtree_opt = FDB_SEQTREE_USE;
}
// 2、使用设置的配置进行初始化
status = fdb_init(&fileConfig);
assert(status == FDB_RESULT_SUCCESS); // 打开数据库
status = fdb_open(&fdbFileHandle, "./testdb", &fileConfig);
assert(status == FDB_RESULT_SUCCESS);
// 打开kvs
fdb_kvs_config kvsConfig = fdb_get_default_kvs_config();
status = fdb_kvs_open_default(fdbFileHandle, &fdbKvsHandle, &kvsConfig);
assert(status == FDB_RESULT_SUCCESS); srand(2017);
std::string k[TEST_FREQUENCY];
for (int i = 0; i < TEST_FREQUENCY; ++i) {
k[i] = (randomstr());
}
std::string v("壹贰叁肆伍陆柒捌玖拾");
v.append(v).append(v).append(v).append(v).append(v); // 测试添加
{
auto start = std::chrono::system_clock::now();
for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = fdb_set_kv(fdbKvsHandle, k[i].data(), k[i].size(), v.data(), v.size());
assert(status == FDB_RESULT_SUCCESS);
}
// 提交操作到磁盘(这里必须commit才能实际写入到磁盘)
fdb_commit(fdbFileHandle, FDB_COMMIT_NORMAL); auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << TEST_FREQUENCY <<"次添加耗时: "
<< double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
<< "秒" << std::endl;
}
// 测试获取
{
auto start = std::chrono::system_clock::now();
void* v2[TEST_FREQUENCY]; size_t v2len[TEST_FREQUENCY];
for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = fdb_get_kv(fdbKvsHandle, k[i].data(), k[i].size(), &v2[i], &v2len[i]);
assert(status == FDB_RESULT_SUCCESS);
}
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << TEST_FREQUENCY <<"次获取耗时: "
<< double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
<< "秒" << std::endl;
// 验证获取结果是否正确
std::string ss;
for (int i = 0; i < TEST_FREQUENCY; ++i) {
ss.assign((const char*)v2[i], v2len[i]);
if (ss != v) {
std::cout << "第 " << i << " 个结果不正确" << std::endl;
std::cout << ss << std::endl;
}
free(v2[i]);
}
}
// 测试修改
{
auto start = std::chrono::system_clock::now();
v.append(v);
for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = fdb_set_kv(fdbKvsHandle, k[i].data(), k[i].size(), v.data(), v.size());
assert(status == FDB_RESULT_SUCCESS);
}
// 提交操作到磁盘(这里必须commit才能实际写入到磁盘)
fdb_commit(fdbFileHandle, FDB_COMMIT_NORMAL); auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << TEST_FREQUENCY <<"次修改耗时: "
<< double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
<< "秒" << std::endl;
} // 测试删除
{
auto start = std::chrono::system_clock::now();
for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = fdb_del_kv(fdbKvsHandle, k[i].data(), k[i].size());
assert(status == FDB_RESULT_SUCCESS);
}
// 提交操作到磁盘(这里必须commit才能实际写入到磁盘)
fdb_commit(fdbFileHandle, FDB_COMMIT_NORMAL); auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << TEST_FREQUENCY <<"次删除耗时: "
<< double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
<< "秒" << std::endl;
} // 关闭数据库
status = fdb_kvs_close(fdbKvsHandle);
assert(status == FDB_RESULT_SUCCESS);
status = fdb_close(fdbFileHandle);
assert(status == FDB_RESULT_SUCCESS);
status = fdb_shutdown();
assert(status == FDB_RESULT_SUCCESS);
return 0;
}

LevelDB和ForestDB简单性能测试(含代码)的更多相关文章

  1. Linux下RocksDB、LevelDB、ForestDB性能测试对比

    简要说明 本次环境与http://www.cnblogs.com/oloroso/p/6306352.html中的一致. 依然是增删查改各测试10000次,每个测试重复5次取平均值. 1.不使用jem ...

  2. .Net core2.0日志组件Log4net、Nlog简单性能测试

    .Net core之Log4net.Nlog简单性能测试 比较log4net.nlog的文件写入性能(.netcore环境),涉及代码和配置如有不正确的地方,还请批评指正. 原创,转载请著名出处:ht ...

  3. snaic和tornado的简单性能测试

    操作系统 : CentOS7.3.1611_x64 Python 版本 : 3.6.8 tornado版本:6.0.2 snaic版本:19.9.0 CPU : Intel(R) Core(TM) i ...

  4. HTML QQ聊天代码 简单的一行代码

    简单的一行代码: <a href="tencent://message/?uin=173007740&Site=&Menu=yes">和17300774 ...

  5. qt简单界面更新代码(菜鸟级)(部分代码)

    qt简单界面更新代码(菜鸟级)(部分代码)self.timers_1=QtCore.QTimer(self)self.timers_1.timeout.connect(self.min_1)self. ...

  6. Greenplum 简单性能测试与分析

    如今,多样的交易模式以及大众消费观念的改变使得数据库应用领域不断扩大,现代的大型分布式应用系统的数据膨胀也对数据库的海量数据处理能力和并行处理能力提出了更高的要求,如何在数据呈现海量扩张的同时提高处理 ...

  7. Spring源码学习:第1步--在Spring源码中添加最简单的Demo代码

    为了最大程度地贴近Spring源码并进行学习,一种比较直接的做法是:直接在Spring源码中加入Demo代码,并进行调试. 参照以前使用Spring的经验,Spring最简单的使用方法是:一个实体类. ...

  8. Flume1.9.0的安装、部署、简单应用(含分布式、与Hadoop3.1.2、Hbase1.4.9的案例)

    目录 目录 前言 什么是Flume? Flume的特点 Flume的可靠性 Flume的可恢复性 Flume的一些核心概念 Flume的官方网站在哪里? Flume在哪里下载以及如何安装? 设置环境变 ...

  9. JS实现简单的运行代码 & 侧边广告

    /* JS实现简单的运行代码功能 */<!doctype html> <html> <head> <meta charset="utf-8" ...

随机推荐

  1. [转]让Nginx支持ThinkPHP的URL重写和PATHINFO

    From : http://www.jzxue.com/wangzhankaifa/php/201108/08-8396.html   ThinkPHP支持通过PATHINFO和URL rewrite ...

  2. Unit Testing of Spring MVC Controllers: Configuration

    Original Link: http://www.petrikainulainen.net/programming/spring-framework/unit-testing-of-spring-m ...

  3. 【UOJ Easy Round #1】

    数论/Trie/并查集 猜数 这题我是这样分析的…… $a*b=g*l=n=k^2 \ and \ (g|a,g|b) \Rightarrow (g*a')*(g*b' )=g*l=k^2 \\ \R ...

  4. 【ContestHunter】【弱省胡策】【Round6】

    KMP/DP+树链剖分+线段树/暴力 今天考的真是……大起大落…… String QwQ题意理解又出错了……(还是说一开始理解了,后来自己又忘了为什么是这样了?) 反正最后的结果就是……我当成:后面每 ...

  5. 使用C++ Builder XE5获取Sensor值之Light Sensor

    献上代码C++代码,仅供參考. 若使用Delphi.请參考文献,http://blogs.embarcadero.com/davidi/2013/12/02/43032/ 一定记得要安装FireMon ...

  6. postgresql共享内存的三个结构体

    本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/16105797 postgresql的共享内存维护主要 ...

  7. C#中byte[] 转 double[] 或 int[] 或 struct结构体

    方法:使用C#调用C++ memcpy实现各种参数类型的内存拷贝 using System.Runtime.InteropServices; public class GlbWSGridDataset ...

  8. Palindrome Partitioning leetcode java

    题目: Given a string s, partition s such that every substring of the partition is a palindrome. Return ...

  9. 国外物联网平台(1):亚马逊AWS IoT

    国外物联网平台(1)——亚马逊AWS IoT 马智 平台定位 AWS IoT是一款托管的云平台,使互联设备可以轻松安全地与云应用程序及其他设备交互. AWS IoT可支持数十亿台设备和数万亿条消息,并 ...

  10. memcached安装和验证

    1> libevent安装 官网down:  http://www.monkey.org 我的网盘down:http://pan.baidu.com/s/1qW8syZi [root@luozh ...