mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-01 05:02:29 +07:00
Add benchmark tests and related configurations for performance evaluation
This commit is contained in:
+11
-1
@@ -219,6 +219,16 @@ style_check: $(STYLE_CHECK_FILES)
|
||||
echo "All files are properly formatted."; \
|
||||
fi
|
||||
|
||||
BENCHMARK_LIBS = -lpthread
|
||||
ifneq ($(OS), Windows_NT)
|
||||
ifeq ($(shell uname -s), Darwin)
|
||||
BENCHMARK_LIBS += -framework CoreFoundation -framework CFNetwork
|
||||
endif
|
||||
endif
|
||||
|
||||
test_benchmark : test_benchmark.cc ../httplib.h Makefile
|
||||
$(CXX) -o $@ -I.. $(CXXFLAGS) test_benchmark.cc gtest/src/gtest-all.cc gtest/src/gtest_main.cc -Igtest -Igtest/include $(BENCHMARK_LIBS)
|
||||
|
||||
test_websocket_heartbeat : test_websocket_heartbeat.cc ../httplib.h Makefile
|
||||
$(CXX) -o $@ -I.. $(CXXFLAGS) test_websocket_heartbeat.cc $(TEST_ARGS)
|
||||
@file $@
|
||||
@@ -254,5 +264,5 @@ cert.pem:
|
||||
./gen-certs.sh
|
||||
|
||||
clean:
|
||||
rm -rf test test_split test_mbedtls test_split_mbedtls test_wolfssl test_split_wolfssl test_no_tls, test_split_no_tls test_proxy test_proxy_mbedtls test_proxy_wolfssl server_fuzzer *.pem *.0 *.o *.1 *.srl httplib.h httplib.cc _build* *.dSYM *_shard_*.log cpp-httplib
|
||||
rm -rf test test_split test_mbedtls test_split_mbedtls test_wolfssl test_split_wolfssl test_no_tls, test_split_no_tls test_proxy test_proxy_mbedtls test_proxy_wolfssl test_benchmark server_fuzzer *.pem *.0 *.o *.1 *.srl httplib.h httplib.cc _build* *.dSYM *_shard_*.log cpp-httplib
|
||||
|
||||
|
||||
@@ -102,71 +102,6 @@ static void read_file(const std::string &path, std::string &out) {
|
||||
fs.read(&out[0], static_cast<std::streamsize>(size));
|
||||
}
|
||||
|
||||
void performance_test(const char *host) {
|
||||
Server svr;
|
||||
|
||||
svr.Get("/benchmark", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_content("Benchmark Response", "text/plain");
|
||||
});
|
||||
|
||||
auto listen_thread = std::thread([&]() { svr.listen(host, PORT); });
|
||||
auto se = detail::scope_exit([&] {
|
||||
svr.stop();
|
||||
listen_thread.join();
|
||||
ASSERT_FALSE(svr.is_running());
|
||||
});
|
||||
|
||||
svr.wait_until_ready();
|
||||
|
||||
Client cli(host, PORT);
|
||||
|
||||
// Warm-up request to establish connection and resolve DNS
|
||||
auto warmup_res = cli.Get("/benchmark");
|
||||
ASSERT_TRUE(warmup_res); // Ensure server is responding correctly
|
||||
|
||||
// Run multiple trials and collect timings
|
||||
const int num_trials = 20;
|
||||
std::vector<int64_t> timings;
|
||||
timings.reserve(num_trials);
|
||||
|
||||
for (int i = 0; i < num_trials; i++) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
auto res = cli.Get("/benchmark");
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto elapsed =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
|
||||
.count();
|
||||
|
||||
// Assertions after timing measurement to avoid overhead
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(StatusCode::OK_200, res->status);
|
||||
|
||||
timings.push_back(elapsed);
|
||||
}
|
||||
|
||||
// Calculate 25th percentile (lower quartile)
|
||||
std::sort(timings.begin(), timings.end());
|
||||
auto p25 = timings[num_trials / 4];
|
||||
|
||||
// Format timings for output
|
||||
std::ostringstream timings_str;
|
||||
timings_str << "[";
|
||||
for (size_t i = 0; i < timings.size(); i++) {
|
||||
if (i > 0) timings_str << ", ";
|
||||
timings_str << timings[i];
|
||||
}
|
||||
timings_str << "]";
|
||||
|
||||
// Localhost HTTP GET should be fast even in CI environments
|
||||
EXPECT_LE(p25, 5) << "25th percentile performance is too slow: " << p25
|
||||
<< "ms (Issue #1777). Timings: " << timings_str.str();
|
||||
}
|
||||
|
||||
TEST(BenchmarkTest, localhost) { performance_test("localhost"); }
|
||||
|
||||
TEST(BenchmarkTest, v6) { performance_test("::1"); }
|
||||
|
||||
class UnixSocketTest : public ::testing::Test {
|
||||
protected:
|
||||
void TearDown() override { std::remove(pathname_.c_str()); }
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
#include <httplib.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
using namespace httplib;
|
||||
|
||||
static const int PORT = 11134;
|
||||
|
||||
static void performance_test(const char *host) {
|
||||
Server svr;
|
||||
|
||||
svr.Get("/benchmark", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_content("Benchmark Response", "text/plain");
|
||||
});
|
||||
|
||||
auto listen_thread = std::thread([&]() { svr.listen(host, PORT); });
|
||||
auto se = detail::scope_exit([&] {
|
||||
svr.stop();
|
||||
listen_thread.join();
|
||||
ASSERT_FALSE(svr.is_running());
|
||||
});
|
||||
|
||||
svr.wait_until_ready();
|
||||
|
||||
Client cli(host, PORT);
|
||||
|
||||
// Warm-up request to establish connection and resolve DNS
|
||||
auto warmup_res = cli.Get("/benchmark");
|
||||
ASSERT_TRUE(warmup_res); // Ensure server is responding correctly
|
||||
|
||||
// Run multiple trials and collect timings
|
||||
const int num_trials = 20;
|
||||
std::vector<int64_t> timings;
|
||||
timings.reserve(num_trials);
|
||||
|
||||
for (int i = 0; i < num_trials; i++) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
auto res = cli.Get("/benchmark");
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto elapsed =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
|
||||
.count();
|
||||
|
||||
// Assertions after timing measurement to avoid overhead
|
||||
ASSERT_TRUE(res);
|
||||
EXPECT_EQ(StatusCode::OK_200, res->status);
|
||||
|
||||
timings.push_back(elapsed);
|
||||
}
|
||||
|
||||
// Calculate 25th percentile (lower quartile)
|
||||
std::sort(timings.begin(), timings.end());
|
||||
auto p25 = timings[num_trials / 4];
|
||||
|
||||
// Format timings for output
|
||||
std::ostringstream timings_str;
|
||||
timings_str << "[";
|
||||
for (size_t i = 0; i < timings.size(); i++) {
|
||||
if (i > 0) timings_str << ", ";
|
||||
timings_str << timings[i];
|
||||
}
|
||||
timings_str << "]";
|
||||
|
||||
// Localhost HTTP GET should be fast even in CI environments
|
||||
EXPECT_LE(p25, 5) << "25th percentile performance is too slow: " << p25
|
||||
<< "ms (Issue #1777). Timings: " << timings_str.str();
|
||||
}
|
||||
|
||||
TEST(BenchmarkTest, localhost) { performance_test("localhost"); }
|
||||
|
||||
TEST(BenchmarkTest, v6) { performance_test("::1"); }
|
||||
Reference in New Issue
Block a user