From df91e9a2d99f569abef6fbf4b2e840a51ece3cc6 Mon Sep 17 00:00:00 2001 From: frankslin Date: Sat, 27 Jun 2026 16:51:37 -0700 Subject: [PATCH 1/2] Add Bazel benchmark target and CodSpeed CI workflow (frankslin/OpenCC#31) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Bazel benchmark target and CodSpeed CI workflow Performance.cpp path resolution now checks env vars before compile-time macros, and in Bazel builds uses Runfiles::Create(argv0) to locate configs, dictionaries, test data, and the opencc CLI binary via the .runfiles/ directory produced by bazel build. Jieba benchmarks are excluded (OPENCC_BENCHMARK_JIEBA_CONFIG_DIR undefined); text_json variants are skipped gracefully during global init when runfiles are not yet available. Detailed Changes: - **Performance.cpp**: - Add GetEnv() helper; add file-scope g_argv0/g_runfiles initialized in main() before benchmark execution. - All path functions follow: env var → Runfiles::Rlocation (BAZEL) → compile-time macro (CMake) → safe default. - Initialize() passes g_argv0 to SimpleConverter so its internal Runfiles::Create(argv0) resolves configs and dictionaries. - BuildBenchmarkConfigs() catches Exception& so text_json creation failures during global init are silently skipped. - **src/benchmark/BUILD.bazel**: new cc_binary; deps include google-benchmark, opencc libs, and @bazel_tools//tools/cpp/runfiles; data covers configs, dictionaries, test data, and command_line binary. - **test/benchmark/BUILD.bazel**: export zuozhuan.txt as benchmark_data. - **.github/workflows/codspeed.yml**: single Ubuntu job; bazel build //src/benchmark:performance; run binary directly via runfiles with only OPENCC_BENCHMARK_TEMP_DIR set; uses CODSPEED_TOKEN_FRANKSLIN secret. * Extend CodSpeed workflow trigger to opencc-wasm-develop branch * Wire CodSpeed compat library and fix benchmark registration order Switch the benchmark binary to @codspeed_google_benchmark_compat (simulation mode) so CodSpeed can identify individual benchmark boundaries; add the required --compilation_mode=dbg and --copt=-O2 flags to the CI workflow. Move RegisterBenchmarks() out of the anonymous namespace and call it in main() after Bazel runfiles are initialised, so text_json variants are no longer silently skipped in Bazel builds. Detailed Changes: - **MODULE.bazel**: - Add bazel_dep for codspeed_google_benchmark_compat 2.1.0 (dev_dependency). - **src/benchmark/BUILD.bazel**: - Replace //deps/google-benchmark:benchmark with @codspeed_google_benchmark_compat//:benchmark. - **src/benchmark/Performance.cpp**: - Remove kBenchmarksRegistered global; add DoRegisterBenchmarks() wrapper in opencc namespace. - Call opencc::DoRegisterBenchmarks() in main() after g_runfiles is initialised. - **.github/workflows/codspeed.yml**: - Pass --@codspeed_google_benchmark_compat//:codspeed_mode=simulation, --compilation_mode=dbg, --copt=-O2 to bazel build. * Fix CodSpeed benchmark naming and suppress DEBUG timing warning Add Performance:: namespace prefix to all registered benchmark names so CodSpeed can identify their source file instead of falling back to unknown_file::. Update BenchmarkGroupName to strip the :: prefix before matching group labels. Add --copt=-DNDEBUG to the workflow build flags so NDEBUG is defined alongside --compilation_mode=dbg, eliminating Google Benchmark's spurious "Library was built as DEBUG" timing warning. --- .github/workflows/codspeed.yml | 60 +++++++++++ MODULE.bazel | 1 + MODULE.bazel.lock | 6 ++ src/benchmark/BUILD.bazel | 26 +++++ src/benchmark/Performance.cpp | 177 ++++++++++++++++++++++++++++----- test/benchmark/BUILD.bazel | 6 ++ 6 files changed, 253 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/codspeed.yml create mode 100644 src/benchmark/BUILD.bazel create mode 100644 test/benchmark/BUILD.bazel diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml new file mode 100644 index 000000000..406df8a16 --- /dev/null +++ b/.github/workflows/codspeed.yml @@ -0,0 +1,60 @@ +name: CodSpeed + +on: + push: + branches: [master, opencc-wasm-develop] + pull_request: + branches: [master, opencc-wasm-develop] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + benchmarks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - uses: bazel-contrib/setup-bazel@0.19.0 + with: + bazelisk-cache: true + repository-cache: true + + - name: Configure BuildBuddy + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository + shell: bash + env: + BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }} + run: | + if [ -n "${BUILDBUDDY_API_KEY}" ]; then + { + echo "build --config=buildbuddy" + echo "build --remote_header=x-buildbuddy-api-key=${BUILDBUDDY_API_KEY}" + echo "build --bes_header=x-buildbuddy-api-key=${BUILDBUDDY_API_KEY}" + } >> .bazelrc.user + echo "BuildBuddy enabled." + else + echo "BUILDBUDDY_API_KEY not set; skipping BuildBuddy config." + fi + + - name: Build benchmark + run: >- + bazel build + --@codspeed_google_benchmark_compat//:codspeed_mode=simulation + --compilation_mode=dbg + --copt=-O2 + --copt=-DNDEBUG + //src/benchmark:performance + + - name: Prepare temp directory + run: mkdir -p /tmp/opencc_bench_temp + + - uses: CodSpeedHQ/action@v3 + with: + token: ${{ secrets.CODSPEED_TOKEN_FRANKSLIN }} + run: >- + OPENCC_BENCHMARK_TEMP_DIR=/tmp/opencc_bench_temp + bazel-bin/src/benchmark/performance diff --git a/MODULE.bazel b/MODULE.bazel index 5c0d637d5..6c880eb16 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -8,6 +8,7 @@ module( bazel_dep(name = "aspect_bazel_lib", version = "2.22.5") bazel_dep(name = "aspect_rules_js", version = "3.2.2") +bazel_dep(name = "codspeed_google_benchmark_compat", version = "2.1.0", dev_dependency = True) bazel_dep(name = "darts-clone", version = "0.32") bazel_dep(name = "googletest", version = "1.17.0.bcr.2", dev_dependency = True) bazel_dep(name = "marisa-trie", version = "0.3.1.bcr.2") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 4a8708542..9ccec429b 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -69,6 +69,10 @@ "https://bcr.bazel.build/modules/bazel_skylib/1.9.0/source.json": "7ad77c1e8c1b84222d9b3f3cae016a76639435744c19330b0b37c0a3c9da7dc0", "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", + "https://bcr.bazel.build/modules/codspeed_core/2.1.0/MODULE.bazel": "78df8ed75ea5a223f92f2286666d09eb335c9cc2b9532ad6f4b633db17ca009e", + "https://bcr.bazel.build/modules/codspeed_core/2.1.0/source.json": "a0398f69220f76845e55f05a41b74f9c276cdb5cd289cf6084922d6284302c5c", + "https://bcr.bazel.build/modules/codspeed_google_benchmark_compat/2.1.0/MODULE.bazel": "53f7154a75180ae4a1ce1f3cb36d546a6e9f3eb0010a7dd4ed484068cb76df43", + "https://bcr.bazel.build/modules/codspeed_google_benchmark_compat/2.1.0/source.json": "2ca9d1aefbc226daa589e543128d5803d44f4eb73e0ecbbcf3fd89a6c75720a6", "https://bcr.bazel.build/modules/darts-clone/0.32/MODULE.bazel": "bdd235e31dd7f2538ff8b3ab3ef09c831349b141afca587d32b487d75c502361", "https://bcr.bazel.build/modules/darts-clone/0.32/source.json": "c65158c152e276f3c59dc0fc0fa746f1ff601e23b0a09812e024fe563e4dc99c", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", @@ -88,6 +92,8 @@ "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0.bcr.1/MODULE.bazel": "e5362dadc90aab6724c83a2cc1e67cbed9c89a05d97fb1f90053c8deb1e445c8", + "https://bcr.bazel.build/modules/libpfm/4.11.0.bcr.1/source.json": "0646414d9037f8aad148781dd760bec90b0b25ac12fda5e03f8aadbd6b9c61e6", "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", "https://bcr.bazel.build/modules/marisa-trie/0.3.1.bcr.2/MODULE.bazel": "8d987298c829b651f00541c89c235185516629c0d17c3d67607ef37e7ad9f322", "https://bcr.bazel.build/modules/marisa-trie/0.3.1.bcr.2/source.json": "72d4c66d20ab99c7ec3659683b57011fa2caa57230d3ba3c9a918d82cdab6109", diff --git a/src/benchmark/BUILD.bazel b/src/benchmark/BUILD.bazel new file mode 100644 index 000000000..518998d1f --- /dev/null +++ b/src/benchmark/BUILD.bazel @@ -0,0 +1,26 @@ +load("@rules_cc//cc:defs.bzl", "cc_binary") + +package(default_visibility = ["//visibility:public"]) + +cc_binary( + name = "performance", + testonly = True, + srcs = ["Performance.cpp"], + includes = [".."], + deps = [ + "@codspeed_google_benchmark_compat//:benchmark", + "//deps/rapidjson-1.1.0:rapidjson", + "//src:exception_lib", + "//src:simple_converter_lib", + "//src:test_utils_utf8_lib", + "@bazel_tools//tools/cpp/runfiles", + ], + data = [ + "//data/config:config", + "//data/dictionary:CJK_Compatibility_Ideographs.txt", + "//data/dictionary:binary_dictionaries", + "//data/dictionary:text_dictionaries", + "//src/tools:command_line", + "//test/benchmark:benchmark_data", + ], +) diff --git a/src/benchmark/Performance.cpp b/src/benchmark/Performance.cpp index 63078cc63..649c9b999 100644 --- a/src/benchmark/Performance.cpp +++ b/src/benchmark/Performance.cpp @@ -44,6 +44,13 @@ #include "SimpleConverter.hpp" #include "TestUtilsUTF8.hpp" +#ifdef BAZEL +#include "tools/cpp/runfiles/runfiles.h" +using BazelRunfiles = bazel::tools::cpp::runfiles::Runfiles; +static const char* g_argv0 = nullptr; +static std::unique_ptr g_runfiles; +#endif + namespace opencc { namespace { @@ -51,6 +58,12 @@ namespace { using JSONDocument = rapidjson::Document; using JSONValue = rapidjson::Value; +// Returns the value of environment variable `name`, or nullptr if unset/empty. +const char* GetEnv(const char* name) noexcept { + const char* val = std::getenv(name); + return (val != nullptr && *val != '\0') ? val : nullptr; +} + struct BenchmarkConfig { std::string name; std::string path; @@ -107,7 +120,14 @@ std::string GetBaseNameWithoutExtension(const std::string& path) { } std::string BenchmarkTempDirectory() { + if (const char* e = GetEnv("OPENCC_BENCHMARK_TEMP_DIR")) { + return std::string(e) + "/"; + } +#ifdef PROJECT_BINARY_DIR return std::string(PROJECT_BINARY_DIR) + "/src/benchmark/"; +#else + return std::string("/tmp/opencc_benchmark/"); +#endif } bool IsAbsolutePath(const std::string& path) { @@ -151,23 +171,59 @@ std::string ResolveConfigPath(const std::string& config_name) { ".json"; } #endif + if (const char* e = GetEnv("OPENCC_BENCHMARK_DATA_DIR")) { + return std::string(e) + "/" + config_name + ".json"; + } +#ifdef BAZEL + if (g_runfiles) { + for (const char* prefix : {"_main", "opencc~"}) { + const std::string path = g_runfiles->Rlocation( + std::string(prefix) + "/data/config/" + config_name + ".json"); + if (IsRegularFile(path)) return path; + } + } + return config_name + ".json"; +#elif defined(PROJECT_SOURCE_DIR) return std::string(PROJECT_SOURCE_DIR) + "/data/config/" + config_name + ".json"; +#else + return config_name + ".json"; +#endif } std::string ResolveTextDictionaryPath(const std::string& dict_file_name) { const std::string text_file_name = ReplaceSuffix(dict_file_name, ".ocd2", ".txt"); - const std::string source_path = - std::string(PROJECT_SOURCE_DIR) + "/data/dictionary/" + text_file_name; - if (IsRegularFile(source_path)) { - return source_path; + + if (const char* e = GetEnv("OPENCC_BENCHMARK_TEXT_DIR")) { + const std::string path = std::string(e) + "/" + text_file_name; + if (IsRegularFile(path)) return path; + throw FileNotFound(text_file_name); } - const std::string generated_path = - std::string(PROJECT_BINARY_DIR) + "/data/" + text_file_name; - if (IsRegularFile(generated_path)) { - return generated_path; +#ifdef BAZEL + if (g_runfiles) { + for (const char* prefix : {"_main", "opencc~"}) { + const std::string path = g_runfiles->Rlocation( + std::string(prefix) + "/data/dictionary/" + text_file_name); + if (IsRegularFile(path)) return path; + } } +#else +#ifdef PROJECT_SOURCE_DIR + { + const std::string source_path = + std::string(PROJECT_SOURCE_DIR) + "/data/dictionary/" + text_file_name; + if (IsRegularFile(source_path)) return source_path; + } +#endif +#ifdef PROJECT_BINARY_DIR + { + const std::string generated_path = + std::string(PROJECT_BINARY_DIR) + "/data/" + text_file_name; + if (IsRegularFile(generated_path)) return generated_path; + } +#endif +#endif throw FileNotFound(text_file_name); } @@ -431,9 +487,9 @@ std::vector BuildBenchmarkConfigs( GetTemporaryTextConfigRegistry().Create(source_path, "text", "benchmark-text"), }); - } catch (const FileNotFound&) { - // Some legacy benchmark configs only ship precompiled ocd2 artifacts. - // Skip the text-json variant when there is no source text dictionary. + } catch (const Exception&) { + // Skip the text-json variant when the config can't be read or text + // dictionaries are unavailable (e.g., Bazel build before runfiles init). } } return configs; @@ -458,15 +514,51 @@ bool IsJiebaConfig(const BenchmarkConfig& config) { #endif std::string OpenccBinaryPath() { + if (const char* e = GetEnv("OPENCC_BENCHMARK_OPENCC_PATH")) return e; +#ifdef BAZEL + if (g_runfiles) { + for (const char* prefix : {"_main", "opencc~"}) { + const std::string path = + g_runfiles->Rlocation(std::string(prefix) + "/src/tools/command_line"); + if (IsRegularFile(path)) return path; + } + } +#endif +#ifdef OPENCC_BENCHMARK_OPENCC_PATH return OPENCC_BENCHMARK_OPENCC_PATH; +#else + return "opencc"; +#endif } std::string SourceConfigDirectory() { + if (const char* e = GetEnv("OPENCC_BENCHMARK_DATA_DIR")) return e; +#ifdef BAZEL + if (g_runfiles) { + const std::string path = g_runfiles->Rlocation("_main/data/config"); + if (!path.empty()) return path; + } +#endif +#ifdef PROJECT_SOURCE_DIR return std::string(PROJECT_SOURCE_DIR) + "/data/config"; +#else + return "."; +#endif } std::string BuildDataDirectory() { + if (const char* e = GetEnv("OPENCC_BENCHMARK_DATA_DIR")) return e; +#ifdef BAZEL + if (g_runfiles) { + const std::string path = g_runfiles->Rlocation("_main/data/dictionary"); + if (!path.empty()) return path; + } +#endif +#ifdef PROJECT_BINARY_DIR return std::string(PROJECT_BINARY_DIR) + "/data"; +#else + return "."; +#endif } struct MeasuredResult { @@ -534,8 +626,19 @@ void RunCommandLineConversion(const BenchmarkConfig& config, } SimpleConverter* Initialize(const BenchmarkConfig& config) { - chdir(PROJECT_BINARY_DIR "/data"); + if (const char* e = GetEnv("OPENCC_BENCHMARK_DATA_DIR")) { + chdir(e); + } +#ifdef PROJECT_BINARY_DIR + else { + chdir(PROJECT_BINARY_DIR "/data"); + } +#endif +#ifdef BAZEL + return new SimpleConverter(config.path, std::vector{}, g_argv0); +#else return new SimpleConverter(config.path); +#endif } void Convert(const SimpleConverter* converter, std::string_view text) { @@ -595,9 +698,12 @@ std::string FormatCounterValue(const benchmark::BenchmarkReporter::Run& run, std::string BenchmarkGroupName(const benchmark::BenchmarkReporter::Run& run) { const std::string name = run.benchmark_name(); - const std::string::size_type slash_pos = name.find('/'); + const std::string::size_type colons_pos = name.find("::"); + const std::string bare_name = + colons_pos != std::string::npos ? name.substr(colons_pos + 2) : name; + const std::string::size_type slash_pos = bare_name.find('/'); const std::string prefix = - slash_pos == std::string::npos ? name : name.substr(0, slash_pos); + slash_pos == std::string::npos ? bare_name : bare_name.substr(0, slash_pos); if (prefix == "BM_Initialization") { return "Initialization"; } @@ -755,8 +861,23 @@ void SetCommandLineCounters(benchmark::State& state, size_t total_input_bytes, } std::string ReadText(const std::string& filename) { - const std::string benchmark_data_dir = PROJECT_SOURCE_DIR "/test/benchmark/"; - const std::string data_path = benchmark_data_dir + filename; + std::string data_path; + if (const char* e = GetEnv("OPENCC_BENCHMARK_TEST_DATA_DIR")) { + data_path = std::string(e) + "/" + filename; + } else { +#ifdef BAZEL + if (g_runfiles) { + data_path = g_runfiles->Rlocation("_main/test/benchmark/" + filename); + } + if (data_path.empty() || !IsRegularFile(data_path)) { + data_path = filename; + } +#elif defined(PROJECT_SOURCE_DIR) + data_path = std::string(PROJECT_SOURCE_DIR) + "/test/benchmark/" + filename; +#else + data_path = filename; +#endif + } std::ifstream stream(data_path.c_str()); return std::string((std::istreambuf_iterator(stream)), std::istreambuf_iterator()); @@ -873,7 +994,7 @@ bool RegisterBenchmarks() { BuildBenchmarkConfigs(InitializationConfigs()); for (const BenchmarkConfig& config : initialization_configs) { benchmark::RegisterBenchmark( - ("BM_Initialization/" + config.name).c_str(), + ("Performance::BM_Initialization/" + config.name).c_str(), [config](benchmark::State& state) { BM_Initialization(state, config); }) ->Unit(benchmark::kMicrosecond); } @@ -882,7 +1003,7 @@ bool RegisterBenchmarks() { BuildBenchmarkConfigs(ConversionConfigs()); for (const BenchmarkConfig& config : conversion_configs) { benchmark::RegisterBenchmark( - ("BM_ConvertLongText/" + config.name).c_str(), + ("Performance::BM_ConvertLongText/" + config.name).c_str(), [config](benchmark::State& state) { BM_ConvertLongText(state, config); }) ->Unit(benchmark::kMillisecond); } @@ -890,7 +1011,7 @@ bool RegisterBenchmarks() { for (const BenchmarkConfig& config : conversion_configs) { for (const int iteration : {100, 1000, 10000, 100000}) { benchmark::RegisterBenchmark( - ("BM_Convert/" + config.name + "/" + std::to_string(iteration)) + ("Performance::BM_Convert/" + config.name + "/" + std::to_string(iteration)) .c_str(), [config, iteration](benchmark::State& state) { BM_Convert(state, config, iteration); @@ -901,7 +1022,7 @@ bool RegisterBenchmarks() { for (const BenchmarkConfig& config : conversion_configs) { benchmark::RegisterBenchmark( - ("BM_CommandLineLongText/" + config.name).c_str(), + ("Performance::BM_CommandLineLongText/" + config.name).c_str(), [config](benchmark::State& state) { BM_CommandLineLongText(state, config); }) @@ -912,7 +1033,7 @@ bool RegisterBenchmarks() { for (const BenchmarkConfig& config : conversion_configs) { for (const int iteration : {100, 1000, 10000, 100000}) { benchmark::RegisterBenchmark( - ("BM_CommandLine/" + config.name + "/" + std::to_string(iteration)) + ("Performance::BM_CommandLine/" + config.name + "/" + std::to_string(iteration)) .c_str(), [config, iteration](benchmark::State& state) { BM_CommandLine(state, config, iteration); @@ -924,13 +1045,23 @@ bool RegisterBenchmarks() { return true; } -const bool kBenchmarksRegistered = RegisterBenchmarks(); - } // namespace +void DoRegisterBenchmarks() { + RegisterBenchmarks(); +} + } // namespace opencc int main(int argc, char** argv) { +#ifdef BAZEL + g_argv0 = argc > 0 ? argv[0] : nullptr; + { + std::string err; + g_runfiles.reset(BazelRunfiles::Create(g_argv0 != nullptr ? g_argv0 : "", &err)); + } +#endif + opencc::DoRegisterBenchmarks(); ::benchmark::Initialize(&argc, argv); if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { return 1; diff --git a/test/benchmark/BUILD.bazel b/test/benchmark/BUILD.bazel new file mode 100644 index 000000000..bfef96d64 --- /dev/null +++ b/test/benchmark/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "benchmark_data", + srcs = ["zuozhuan.txt"], +) From 40ae09455eeedc36283c6ddd551f775035a2ca14 Mon Sep 17 00:00:00 2001 From: Frank Lin Date: Sat, 27 Jun 2026 17:02:08 -0700 Subject: [PATCH 2/2] Focus CodSpeed suite on pure conversion CPU hot path Add LongTextConversionConfigs() covering all 14 conversion directions and use it for BM_ConvertLongText, so every conversion chain (s2t, s2twp, t2s, s2hk, jp2t, etc.) gets its own regression-detectable benchmark. Restrict the CodSpeed workflow to BM_ConvertLongText.*ocd2: ocd2 format means dictionaries are already loaded so the benchmark measures only the mmseg segmentation and marisa-trie lookup CPU cost, not I/O. Initialization, BM_Convert, and command-line benchmarks remain available for local runs but are excluded from CodSpeed instrumentation. --- .github/workflows/codspeed.yml | 1 + src/benchmark/Performance.cpp | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 406df8a16..804d6ff91 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -58,3 +58,4 @@ jobs: run: >- OPENCC_BENCHMARK_TEMP_DIR=/tmp/opencc_bench_temp bazel-bin/src/benchmark/performance + '--benchmark_filter=BM_ConvertLongText.*ocd2' diff --git a/src/benchmark/Performance.cpp b/src/benchmark/Performance.cpp index 649c9b999..f0df2a40f 100644 --- a/src/benchmark/Performance.cpp +++ b/src/benchmark/Performance.cpp @@ -466,6 +466,17 @@ std::vector InitializationConfigs() { return configs; } +std::vector LongTextConversionConfigs() { + std::vector configs = { + "hk2s", "hk2t", "jp2t", "s2hk", "s2t", "s2tw", "s2twp", + "t2hk", "t2jp", "t2s", "t2tw", "tw2s", "tw2sp", "tw2t", + }; +#ifdef OPENCC_BENCHMARK_JIEBA_CONFIG_DIR + configs.push_back("s2twp_jieba"); +#endif + return configs; +} + std::vector ConversionConfigs() { std::vector configs = {"s2t", "s2twp"}; #ifdef OPENCC_BENCHMARK_JIEBA_CONFIG_DIR @@ -999,15 +1010,17 @@ bool RegisterBenchmarks() { ->Unit(benchmark::kMicrosecond); } - const std::vector conversion_configs = - BuildBenchmarkConfigs(ConversionConfigs()); - for (const BenchmarkConfig& config : conversion_configs) { + const std::vector long_text_configs = + BuildBenchmarkConfigs(LongTextConversionConfigs()); + for (const BenchmarkConfig& config : long_text_configs) { benchmark::RegisterBenchmark( ("Performance::BM_ConvertLongText/" + config.name).c_str(), [config](benchmark::State& state) { BM_ConvertLongText(state, config); }) ->Unit(benchmark::kMillisecond); } + const std::vector conversion_configs = + BuildBenchmarkConfigs(ConversionConfigs()); for (const BenchmarkConfig& config : conversion_configs) { for (const int iteration : {100, 1000, 10000, 100000}) { benchmark::RegisterBenchmark(