LevelDB和ForestDB简单性能测试(含代码)
测试环境简单说明
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参数优化。
测试结果
对LevelDB和ForestDB进行简单的性能测试。
两个都在单线程下进行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简单性能测试(含代码)的更多相关文章
- Linux下RocksDB、LevelDB、ForestDB性能测试对比
简要说明 本次环境与http://www.cnblogs.com/oloroso/p/6306352.html中的一致. 依然是增删查改各测试10000次,每个测试重复5次取平均值. 1.不使用jem ...
- .Net core2.0日志组件Log4net、Nlog简单性能测试
.Net core之Log4net.Nlog简单性能测试 比较log4net.nlog的文件写入性能(.netcore环境),涉及代码和配置如有不正确的地方,还请批评指正. 原创,转载请著名出处:ht ...
- snaic和tornado的简单性能测试
操作系统 : CentOS7.3.1611_x64 Python 版本 : 3.6.8 tornado版本:6.0.2 snaic版本:19.9.0 CPU : Intel(R) Core(TM) i ...
- HTML QQ聊天代码 简单的一行代码
简单的一行代码: <a href="tencent://message/?uin=173007740&Site=&Menu=yes">和17300774 ...
- qt简单界面更新代码(菜鸟级)(部分代码)
qt简单界面更新代码(菜鸟级)(部分代码)self.timers_1=QtCore.QTimer(self)self.timers_1.timeout.connect(self.min_1)self. ...
- Greenplum 简单性能测试与分析
如今,多样的交易模式以及大众消费观念的改变使得数据库应用领域不断扩大,现代的大型分布式应用系统的数据膨胀也对数据库的海量数据处理能力和并行处理能力提出了更高的要求,如何在数据呈现海量扩张的同时提高处理 ...
- Spring源码学习:第1步--在Spring源码中添加最简单的Demo代码
为了最大程度地贴近Spring源码并进行学习,一种比较直接的做法是:直接在Spring源码中加入Demo代码,并进行调试. 参照以前使用Spring的经验,Spring最简单的使用方法是:一个实体类. ...
- Flume1.9.0的安装、部署、简单应用(含分布式、与Hadoop3.1.2、Hbase1.4.9的案例)
目录 目录 前言 什么是Flume? Flume的特点 Flume的可靠性 Flume的可恢复性 Flume的一些核心概念 Flume的官方网站在哪里? Flume在哪里下载以及如何安装? 设置环境变 ...
- JS实现简单的运行代码 & 侧边广告
/* JS实现简单的运行代码功能 */<!doctype html> <html> <head> <meta charset="utf-8" ...
随机推荐
- Visual Studio提示“无法启动IIS Express Web服务器”的解决方法 vs调试显示无法显示此页面 ,vs调试浏览器白页
有时,在使用Visual Studio运行ASP.NET项目时,会提示“无法启动IIS Express Web服务器”,无法运行,如图: 这一般出现在重装系统之后,或者项目是从别的电脑上复制过来的.解 ...
- DatabaseMirroring搭建
1. 概述 数据库镜像维护一个数据库的两个副本,这两个副本必须驻留在不同的 SQL Server 数据库引擎 服务器实例上.通常,这些服务器实例驻留在不同位置的计算机上.启动数据库上的数据库镜像 ...
- Google和Baidu的站内搜索代码
<!-- SiteSearch Google --> <form method="get" action="http://www.google.com/ ...
- CF 329A(Purification-贪心-非DLX)
A. Purification time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
- QT TCP网络编程
首先介绍一下TCP:(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.相比而言UDP,就是开放式.无连接.不可靠的传输层 ...
- 第十章 常用的JVM参数记录
GC -XX:+PrintGC 打印GC日志 -XX:+PrintGCDetails 打印详细的GC日志 -Xloggc:/var/gc.log 将GC日志打印在根目录的var文件夹下的g ...
- ESP32那些事儿(六):功能开发之蓝牙及WiFi功能
蓝牙和WIFI是ESP32的核心功能,蓝牙和wifi的共存也是esp32的独门武功,但时候后续也会发现共存的时候会有很多问题.不管怎样,蓝牙和wifi在esp-idf中有很多的例子,大家都可以参考.本 ...
- EntityFramework6 快速入门教程【转】
https://www.cnblogs.com/wujingtao/p/5401113.html 不得不说EF在国内实在是太小众,相关的技术文章真实屈指可数,而且很多文章都很旧了,里面使用的版本跟如今 ...
- Asp.net Page_ClientValidate 的应用和跳过
其实网上说道的Page_ClientValidate的博客其实有很多.这里就不列举了,最近在开发遇到一个问题给大家分享一下, 整理后的代码 如下: HTML code, <%@ Page Lan ...
- Hadoop家族学习路线图v
主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pig, HBase, Sqoop, Mahout, Zookeeper, Avro, Ambari, Chukwa,新增加的项 ...