282 lines
6.5 KiB
C++
282 lines
6.5 KiB
C++
#include <iostream>
|
|
#include <string>
|
|
#include <random>
|
|
#include <httplib.h>
|
|
#include <benchmark/benchmark.h>
|
|
#include <shm.h>
|
|
const size_t data_length = 32; // 随机数据长度
|
|
const std::string server_addr = "http://localhost:8080";
|
|
|
|
// 生成随机字符串
|
|
static std::string generate_random_string(size_t length)
|
|
{
|
|
static const char alphanum[] =
|
|
"0123456789"
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
"abcdefghijklmnopqrstuvwxyz";
|
|
|
|
static std::random_device rd;
|
|
static std::mt19937 gen(rd());
|
|
static std::uniform_int_distribution<> dis(0, sizeof(alphanum) - 2);
|
|
|
|
std::string str;
|
|
str.reserve(length);
|
|
for (size_t i = 0; i < length; ++i)
|
|
{
|
|
str += alphanum[dis(gen)];
|
|
}
|
|
return str;
|
|
}
|
|
|
|
|
|
// Http 写操作
|
|
static void HttpWrite(benchmark::State& state)
|
|
{
|
|
httplib::Client cli(server_addr);
|
|
|
|
for (auto _ : state)
|
|
{
|
|
std::string data = generate_random_string(data_length);
|
|
auto res = cli.Post("/write", data, "text/plain");
|
|
|
|
if (res && res->status == 200)
|
|
{
|
|
benchmark::DoNotOptimize(res->body);
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Write failed!" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Http 读操作
|
|
static void HttpRead(benchmark::State& state)
|
|
{
|
|
httplib::Client cli(server_addr);
|
|
|
|
for (auto _ : state)
|
|
{
|
|
auto res = cli.Get("/read");
|
|
|
|
if (res && res->status == 200)
|
|
{
|
|
benchmark::DoNotOptimize(res->body);
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Read failed!" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void HttpWriteRead(benchmark::State& state)
|
|
{
|
|
httplib::Client cli(server_addr);
|
|
|
|
for (auto _ : state)
|
|
{
|
|
// write
|
|
std::string data = generate_random_string(data_length);
|
|
auto write_res = cli.Post("/write", data, "text/plain");
|
|
|
|
// 写入断言
|
|
if (!write_res)
|
|
{
|
|
state.SkipWithError("Write request failed - no response");
|
|
continue;
|
|
}
|
|
assert(write_res->status == 200 && "Write operation failed");
|
|
assert(write_res->body == "OK" && "Unexpected write response");
|
|
|
|
// read
|
|
auto read_res = cli.Get("/read");
|
|
|
|
// 读取断言
|
|
if (!read_res)
|
|
{
|
|
state.SkipWithError("Read request failed - no response");
|
|
continue;
|
|
}
|
|
assert(read_res->status == 200 && "Read operation failed");
|
|
assert(read_res->body == data && "Read data doesn't match written data");
|
|
|
|
// 防止编译器优化掉结果
|
|
benchmark::DoNotOptimize(write_res);
|
|
benchmark::DoNotOptimize(read_res);
|
|
}
|
|
}
|
|
|
|
|
|
static void HttpWriteWithLock(benchmark::State& state)
|
|
{
|
|
httplib::Client cli(server_addr);
|
|
|
|
for (auto _ : state)
|
|
{
|
|
std::string data = generate_random_string(data_length);
|
|
auto res = cli.Post("/write/lock", data, "text/plain");
|
|
|
|
if (res && res->status == 200)
|
|
{
|
|
benchmark::DoNotOptimize(res->body);
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Write failed!" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Http 读操作
|
|
static void HttpReadWithLock(benchmark::State& state)
|
|
{
|
|
httplib::Client cli(server_addr);
|
|
|
|
for (auto _ : state)
|
|
{
|
|
auto res = cli.Get("/read/lock");
|
|
|
|
if (res && res->status == 200)
|
|
{
|
|
benchmark::DoNotOptimize(res->body);
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Read failed!" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void HttpWriteReadWithLock(benchmark::State& state)
|
|
{
|
|
httplib::Client cli(server_addr);
|
|
|
|
for (auto _ : state)
|
|
{
|
|
// write
|
|
std::string data = generate_random_string(data_length);
|
|
auto write_res = cli.Post("/write/lock", data, "text/plain");
|
|
|
|
// 写入断言
|
|
if (!write_res)
|
|
{
|
|
state.SkipWithError("Write request failed - no response");
|
|
continue;
|
|
}
|
|
assert(write_res->status == 200 && "Write operation failed");
|
|
assert(write_res->body == "OK" && "Unexpected write response");
|
|
|
|
// read
|
|
auto read_res = cli.Get("/read/lock");
|
|
|
|
// 读取断言
|
|
if (!read_res)
|
|
{
|
|
state.SkipWithError("Read request failed - no response");
|
|
continue;
|
|
}
|
|
assert(read_res->status == 200 && "Read operation failed");
|
|
assert(read_res->body == data && "Read data doesn't match written data");
|
|
|
|
// 防止编译器优化掉结果
|
|
benchmark::DoNotOptimize(write_res);
|
|
benchmark::DoNotOptimize(read_res);
|
|
}
|
|
}
|
|
|
|
|
|
// =============================================== Shm ===============================================
|
|
// Shm 写操作
|
|
static void ShmWrite(benchmark::State& state)
|
|
{
|
|
for (auto _ : state)
|
|
{
|
|
std::string data = generate_random_string(data_length);
|
|
auto res = shm_write(data);
|
|
|
|
if (res)
|
|
{
|
|
benchmark::DoNotOptimize(res);
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Write failed!" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Shm 读操作
|
|
static void ShmRead(benchmark::State& state)
|
|
{
|
|
for (auto _ : state)
|
|
{
|
|
auto res = shm_read();
|
|
|
|
if (!res.empty())
|
|
{
|
|
benchmark::DoNotOptimize(res);
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Read failed!" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void ShmReadWrite(benchmark::State& state)
|
|
{
|
|
for (auto _ : state)
|
|
{
|
|
// write
|
|
std::string data = generate_random_string(data_length);
|
|
auto write_res = shm_write(data);
|
|
|
|
if (write_res)
|
|
{
|
|
benchmark::DoNotOptimize(write_res);
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Write failed!" << std::endl;
|
|
}
|
|
|
|
// read
|
|
auto read_res = shm_read();
|
|
|
|
// 读取断言
|
|
if (!read_res.empty())
|
|
{
|
|
benchmark::DoNotOptimize(read_res);
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Read failed!" << std::endl;
|
|
}
|
|
|
|
assert(read_res == data && "Read data doesn't match written data");
|
|
|
|
// 防止编译器优化掉结果
|
|
benchmark::DoNotOptimize(write_res);
|
|
benchmark::DoNotOptimize(read_res);
|
|
}
|
|
}
|
|
|
|
// 注册基准测试
|
|
// HTTP 共享数据
|
|
BENCHMARK(HttpWrite);
|
|
BENCHMARK(HttpRead);
|
|
BENCHMARK(HttpWriteRead);
|
|
// HTTP 带锁共享数据
|
|
BENCHMARK(HttpWriteWithLock);
|
|
BENCHMARK(HttpReadWithLock);
|
|
BENCHMARK(HttpWriteReadWithLock);
|
|
// Shm 带锁共享数据
|
|
BENCHMARK(ShmWrite);
|
|
BENCHMARK(ShmRead);
|
|
|
|
BENCHMARK_MAIN();
|