| 57 | } |
| 58 | |
| 59 | int main(int argc, char** argv) { |
| 60 | std::string resourceZip; |
| 61 | std::vector<std::string> extraPaths; |
| 62 | |
| 63 | // Collect non-positional args first |
| 64 | int argIdx = 1; |
| 65 | while (argIdx < argc && std::string(argv[argIdx]) == "--resource-zip") { |
| 66 | if (argIdx + 1 >= argc) { |
| 67 | std::cerr << "error: --resource-zip requires an argument\n"; |
| 68 | return 1; |
| 69 | } |
| 70 | resourceZip = argv[argIdx + 1]; |
| 71 | argIdx += 2; |
| 72 | } |
| 73 | |
| 74 | if (argIdx + 1 >= argc) { |
| 75 | std::cerr << "usage: speed_benchmark [--resource-zip <zip>] <config> <corpus_file>" |
| 76 | " [reps] [-- <search_path>...]\n"; |
| 77 | return 1; |
| 78 | } |
| 79 | |
| 80 | const std::string config = argv[argIdx++]; |
| 81 | const std::string corpusFile = argv[argIdx++]; |
| 82 | int reps = 20; |
| 83 | |
| 84 | for (int i = argIdx; i < argc; i++) { |
| 85 | if (std::string(argv[i]) == "--") { |
| 86 | for (int j = i + 1; j < argc; j++) { |
| 87 | extraPaths.push_back(argv[j]); |
| 88 | } |
| 89 | break; |
| 90 | } |
| 91 | reps = std::stoi(argv[i]); |
| 92 | } |
| 93 | |
| 94 | const std::string corpus = ReadFile(corpusFile); |
| 95 | const size_t corpusBytes = corpus.size(); |
| 96 | |
| 97 | // Count Unicode code points for a fair comparison with JS benchmark. |
| 98 | size_t corpusChars = 0; |
| 99 | for (const char* p = corpus.data(), *end = p + corpus.size(); p < end;) { |
| 100 | const size_t n = opencc::UTF8Util::NextCharLength(p); |
| 101 | p += (n > 0 && p + n <= end) ? n : 1; |
| 102 | ++corpusChars; |
| 103 | } |
| 104 | |
| 105 | // ── init ────────────────────────────────────────────────────────────────── |
| 106 | auto t0 = Clock::now(); |
| 107 | std::unique_ptr<opencc::SimpleConverter> converterPtr; |
| 108 | if (!resourceZip.empty()) { |
| 109 | auto provider = std::make_shared<opencc::ZipResourceProvider>(resourceZip); |
| 110 | converterPtr = std::make_unique<opencc::SimpleConverter>(config, provider); |
| 111 | } else { |
| 112 | converterPtr = std::make_unique<opencc::SimpleConverter>(config, extraPaths); |
| 113 | } |
| 114 | auto t1 = Clock::now(); |
| 115 | const double initMs = ElapsedMs(t0, t1); |
| 116 | |