Browse Source

benchmark

xry
xxy 9 months ago
parent
commit
f5a7f355c2
1 changed files with 98 additions and 77 deletions
  1. +98
    -77
      test/benchmark_4leveldb.cpp

+ 98
- 77
test/benchmark_4leveldb.cpp View File

@ -1,108 +1,129 @@
#include <cassert>
#include <string>
#include <cassert>
#include <string>
#include <iostream> #include <iostream>
#include <cmath>
#include <chrono> #include <chrono>
#include "leveldb/db.h"
#define TEST_FREQUENCY (10000)
char* randomstr()
{
static char buf[1024];
int len = rand() % 768 + 255;
#include "leveldb/db.h"
// 配置
const int TEST_EXPONENT = 4;
const int TEST_FREQUENCY = static_cast<int>(std::pow(10, TEST_EXPONENT));
const int MIN_STR_LEN = 255;
const int MAX_STR_LEN = 1024;
const std::string DB_PATH = "./db_benchmark";
const std::string CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 多语言
const std::string BASE_VALUE = "こんにちは世界!Hello World! Привет, мир! ¡Hola Mundo! 你好,世界!Bonjour le monde! Hallo Welt!";
// 莎士比亚
// const std::string BASE_VALUE = "To be, or not to be, that is the question: Whether 'tis nobler in the mind to suffer the slings and arrows of outrageous fortune, or to take arms against a sea of troubles and by opposing end them.";
// 超长字符
// const std::string BASE_VALUE = []() {
// std::string base = "壹贰叁肆伍陆柒捌玖拾";
// std::string long_text;
// for (int i = 0; i < 100; ++i) { // 重复 100 次
// long_text += base;
// }
// return long_text;
// }();
// 随机字符串生成
std::string randomStr() {
int len = rand() % (MAX_STR_LEN - MIN_STR_LEN + 1) + MIN_STR_LEN;
std::string str(len, '\0');
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
buf[i] = 'A' + rand() % 26;
str[i] = CHARSET[rand() % CHARSET.size()];
} }
buf[len] = '\0';
return buf;
return str;
} }
int main()
{
// 计算并输出耗时的模板函数
template<typename Func>
void measureTime(const std::string& operation, Func func) {
auto start = std::chrono::system_clock::now();
func();
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << TEST_FREQUENCY << "" << operation << "耗时: "
<< double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den
<< "" << std::endl;
}
int main() {
leveldb::DB* db; leveldb::DB* db;
leveldb::Options options; leveldb::Options options;
options.create_if_missing = true; options.create_if_missing = true;
// 打开数据库 // 打开数据库
leveldb::Status status = leveldb::DB::Open(options, "./testdb", &db);
leveldb::Status status = leveldb::DB::Open(options, DB_PATH, &db);
assert(status.ok()); assert(status.ok());
std::cout << "数据库已打开: " << DB_PATH << std::endl;
srand(2017); srand(2017);
std::string k[TEST_FREQUENCY];
// 生成测试数据
std::string keys[TEST_FREQUENCY];
for (int i = 0; i < TEST_FREQUENCY; ++i) { for (int i = 0; i < TEST_FREQUENCY; ++i) {
k[i] = (randomstr());
keys[i] = randomStr();
}
std::string value = BASE_VALUE;
for (int i = 0; i < 4; ++i) {
value += value; // 扩展 base value
} }
std::string v("壹贰叁肆伍陆柒捌玖拾");
v.append(v).append(v).append(v).append(v).append(v);
// 测试添加 // 测试添加
{
auto start = std::chrono::system_clock::now();
measureTime("添加", [&]() {
for (int i = 0; i < TEST_FREQUENCY; ++i) { for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = db->Put(leveldb::WriteOptions(), k[i], v);
status = db->Put(leveldb::WriteOptions(), keys[i], value);
assert(status.ok()); 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];
measureTime("获取", [&]() {
std::string retrievedValues[TEST_FREQUENCY];
for (int i = 0; i < TEST_FREQUENCY; ++i) { for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = db->Get(leveldb::ReadOptions(), k[i], &v2[i]);
status = db->Get(leveldb::ReadOptions(), keys[i], &retrievedValues[i]);
assert(status.ok()); assert(status.ok());
assert(retrievedValues[i] == value); // 验证获取结果
} }
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);
measureTime("修改", [&]() {
std::string newValue = value + value;
for (int i = 0; i < TEST_FREQUENCY; ++i) { for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = db->Put(leveldb::WriteOptions(), k[i], v);
status = db->Put(leveldb::WriteOptions(), keys[i], newValue);
assert(status.ok()); 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();
measureTime("删除", [&]() {
for (int i = 0; i < TEST_FREQUENCY; ++i) { for (int i = 0; i < TEST_FREQUENCY; ++i) {
status = db->Delete(leveldb::WriteOptions(), k[i]);
status = db->Delete(leveldb::WriteOptions(), keys[i]);
assert(status.ok()); 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;
}
});
if (db) {
delete db; delete db;
db = nullptr;
}
std::cout << "测试完成,数据库已关闭。" << std::endl;
// 删除数据库目录
#ifdef _WIN32
std::string command = "rd /s /q \"" + DB_PATH + "\""; // Windows 删除目录
#else
std::string command = "rm -rf \"" + DB_PATH + "\""; // Linux/macOS 删除目录
#endif
if (std::system(command.c_str()) == 0) {
std::cout << "数据库目录已删除: " << DB_PATH << std::endl;
} else {
std::cerr << "警告: 数据库目录删除失败,请手动检查!" << std::endl;
}
return 0; return 0;
}
}

Loading…
Cancel
Save