Files
ViewDesignEngine/tests/benchmark/bench_io_perf.cpp
T
茂之钳 7b76689ea1
CI / Build & Test (push) Failing after 41s
CI / Release Build (push) Failing after 30s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
feat(v11): CI/CD + regression tests + fuzzing + benchmarks + code quality
v11.1 — Test Infrastructure (14 files):
- .github/workflows/ci.yml: Ubuntu 22.04 + GCC 11, auto ctest on push
- tests/regression/: degenerate geometry, extreme coords, thin wall, large models
- tests/fuzz/: SDF random CSG, random booleans, format round-trip, continuous mode
- tests/benchmark/: boolean perf, MC perf, IO perf benchmarks
- docs/benchmark-report.md: benchmark template

v11.2 — Code Quality + Docs:
- .clang-tidy: 15 check categories, 22 exclusions
- .github/workflows/static-analysis.yml: clang-tidy CI scan
- CODEOWNERS, SECURITY.md
- docs: API overview, testing guide, contributing guide
- README: module capability overview table

Pending: binary formats + curve projection (retrying)
2026-07-27 01:10:58 +08:00

195 lines
5.6 KiB
C++

/// @file bench_io_perf.cpp
/// @brief 导入/导出性能基准测试
///
/// 测试 IGES/STEP 格式的导出耗时和导入耗时。
#include <gtest/gtest.h>
#include "vde/brep/brep.h"
#include "vde/brep/modeling.h"
#include "vde/brep/iges_export.h"
#include "vde/brep/iges_import.h"
#include "vde/brep/step_export.h"
#include "vde/brep/step_import.h"
#include <chrono>
#include <iostream>
#include <iomanip>
#include <vector>
using namespace vde::brep;
using namespace std::chrono;
struct IOBenchmarkResult {
std::string name;
double time_ms;
size_t data_size_bytes;
};
static std::vector<IOBenchmarkResult> g_io_results;
static double measure_ms(std::function<void()> fn, int iterations = 3) {
double best = 1e18;
for (int i = 0; i < iterations; ++i) {
auto start = high_resolution_clock::now();
fn();
auto end = high_resolution_clock::now();
double ms = duration_cast<microseconds>(end - start).count() / 1000.0;
if (ms < best) best = ms;
}
return best;
}
static void record_io(const std::string& name, double ms, size_t bytes) {
g_io_results.push_back({name, ms, bytes});
std::cout << " [BENCH] " << std::left << std::setw(40) << name
<< std::right << std::setw(10) << std::fixed << std::setprecision(2)
<< ms << " ms"
<< " (data=" << bytes << " bytes)"
<< std::endl;
}
// ═══════════════════════════════════════════════
// IGES 基准
// ═══════════════════════════════════════════════
TEST(BenchmarkIO, IGES_Export_SingleBody) {
auto body = make_box(10.0, 5.0, 3.0);
std::string result;
double ms = measure_ms([&]() {
result = export_iges({body});
}, 5);
EXPECT_FALSE(result.empty());
record_io("IO.IGES.Export/SingleBox", ms, result.size());
}
TEST(BenchmarkIO, IGES_Export_Sphere) {
auto body = make_sphere(5.0, 16, 8);
std::string result;
double ms = measure_ms([&]() {
result = export_iges({body});
}, 5);
EXPECT_FALSE(result.empty());
record_io("IO.IGES.Export/Sphere16x8", ms, result.size());
}
TEST(BenchmarkIO, IGES_RoundTrip_Box) {
auto body = make_box(10.0, 5.0, 3.0);
// Export
std::string iges = export_iges({body});
// Import benchmark
double ms = measure_ms([&]() {
auto loaded = import_iges_from_string(iges);
(void)loaded.size();
}, 5);
auto loaded = import_iges_from_string(iges);
EXPECT_FALSE(loaded.empty());
record_io("IO.IGES.Import/SingleBox", ms, iges.size());
}
// ═══════════════════════════════════════════════
// STEP 基准
// ═══════════════════════════════════════════════
TEST(BenchmarkIO, STEP_Export_SingleBody) {
auto body = make_box(10.0, 5.0, 3.0);
std::string result;
double ms = measure_ms([&]() {
result = export_step({body});
}, 5);
EXPECT_FALSE(result.empty());
record_io("IO.STEP.Export/SingleBox", ms, result.size());
}
TEST(BenchmarkIO, STEP_Export_Sphere) {
auto body = make_sphere(5.0, 16, 8);
std::string result;
double ms = measure_ms([&]() {
result = export_step({body});
}, 5);
EXPECT_FALSE(result.empty());
record_io("IO.STEP.Export/Sphere16x8", ms, result.size());
}
TEST(BenchmarkIO, STEP_Export_Cylinder) {
auto body = make_cylinder(3.0, 10.0, 32);
std::string result;
double ms = measure_ms([&]() {
result = export_step({body});
}, 5);
EXPECT_FALSE(result.empty());
record_io("IO.STEP.Export/Cylinder32", ms, result.size());
}
TEST(BenchmarkIO, STEP_RoundTrip_Box) {
auto body = make_box(10.0, 5.0, 3.0);
std::string step = export_step({body});
double ms = measure_ms([&]() {
auto loaded = import_step_from_string(step);
(void)loaded.size();
}, 5);
auto loaded = import_step_from_string(step);
EXPECT_FALSE(loaded.empty());
record_io("IO.STEP.Import/SingleBox", ms, step.size());
}
// ═══════════════════════════════════════════════
// 大规模数据IO基准
// ═══════════════════════════════════════════════
TEST(BenchmarkIO, STEP_Export_LargeModel) {
// 高细分球体 → 大量面 → 大 STEP 文件
auto body = make_sphere(5.0, 32, 16);
std::string result;
double ms = measure_ms([&]() {
result = export_step({body});
}, 3);
EXPECT_FALSE(result.empty());
record_io("IO.STEP.Export/LargeSphere32x16", ms, result.size());
}
TEST(BenchmarkIO, IGES_Export_LargeModel) {
auto body = make_sphere(5.0, 32, 16);
std::string result;
double ms = measure_ms([&]() {
result = export_iges({body});
}, 3);
EXPECT_FALSE(result.empty());
record_io("IO.IGES.Export/LargeSphere32x16", ms, result.size());
}
TEST(BenchmarkIO, MultiBody_Export) {
// 多体导出
std::vector<BrepModel> bodies = {
make_box(3.0, 3.0, 3.0),
make_sphere(2.0, 12, 6),
make_cylinder(1.0, 5.0, 16),
make_box(1.0, 1.0, 10.0),
};
std::string result;
double ms = measure_ms([&]() {
result = export_step(bodies);
}, 3);
EXPECT_FALSE(result.empty());
record_io("IO.STEP.Export/MultiBody(4)", ms, result.size());
}