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" ...
随机推荐
- [转]Win7与虚拟机VMware下运行的Ubuntu共享文件夹
From : http://blog.csdn.net/gaojinshan/article/details/9231853 安装VMware Tools,在VMware面板上选择“虚拟机-重新安装V ...
- POJ 1719 Shooting Contest(二分图匹配)
POJ 1719 Shooting Contest id=1719" target="_blank" style="">题目链接 题意:给定一个 ...
- Java Collection Framework : List
摘要: List 是 Java Collection Framework的重要成员,详细包括List接口及其全部的实现类.由于List接口继承了Collection接口,所以List拥有Collect ...
- Tomcat访问(access)日志配置
在tomcat的access中打印出请求的情况可以帮助我们分析问题,通常比较关注的有访问IP.线程号.访问url.返回状态码.访问时间.持续时间. 最近在跟一个图片请求超时的问题,需要在项目的acce ...
- 附9 elasticsearch-curator + Linux定时任务
官网教程入口:https://www.elastic.co/guide/en/elasticsearch/client/curator/current/index.html 一.下载安装 下载:sud ...
- Python二维数组构造
周末用python要写个算法用到来二维数组, 一时间还不知道python怎么构造多维数组出来.看到一段不错的代码, 记录一下. Python使用list嵌套实现多维数组, PHP可以使用array嵌套 ...
- easyui简单使用
easyui近期一直都比较流行,虽然它在效果上被extjs爆了,它的使用难度低,在IE6下表现不错,的确受到了广泛企业程序员的好评. 但是他的API说明还是比较简陋的,刚上手可能还需要摸索一下,为什么 ...
- 详解vue组件的keep-alive
<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM. <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是 ...
- c#:对两个字符串大小比较(不使用c#/java内部的比较函数),按升序排序
题目:首先需要实现一个函数:两个字符串大小比较(不得使用c#/java系统函数)的自定义函数:之后对一个字符串数据进行按升序排序(在排序过程中使用字符串大小比较时,使用自定义的字符串大小比较函数). ...
- 转: 一个程序员的Java和C++学习之路(整理)
http://blog.csdn.net/ajian005/article/details/8003655 http://m.blog.csdn.net/xugangwen/article/detai ...