1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // This program measures the time taken to decode the given JSON files (the
6 // command line arguments). It is for manual benchmarking.
9 // $ ninja -C out/foobar json_perftest_decodebench
10 // $ out/foobar/json_perftest_decodebench -a -n=10 the/path/to/your/*.json
12 // The -n=10 switch controls the number of iterations. It defaults to 1.
14 // The -a switch means to print 1 non-comment line per input file (the average
15 // iteration time). Without this switch (the default), it prints n non-comment
16 // lines per input file (individual iteration times). For a single input file,
17 // building and running this program before and after a particular commit can
18 // work well with the 'ministat' tool: https://github.com/thorduri/ministat
24 #include "base/command_line.h"
25 #include "base/files/file_util.h"
26 #include "base/json/json_reader.h"
27 #include "base/logging.h"
28 #include "base/time/time.h"
30 int main(int argc, char* argv[]) {
31 if (!base::ThreadTicks::IsSupported()) {
32 std::cout << "# base::ThreadTicks is not supported\n";
35 base::ThreadTicks::WaitUntilInitialized();
37 base::CommandLine::Init(argc, argv);
38 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
39 bool average = command_line->HasSwitch("a");
41 std::string iterations_str = command_line->GetSwitchValueASCII("n");
42 if (!iterations_str.empty()) {
43 iterations = atoi(iterations_str.c_str());
45 std::cout << "# invalid -n command line switch\n";
51 std::cout << "# Microseconds (μs), n=" << iterations << ", averaged"
54 std::cout << "# Microseconds (μs), n=" << iterations << std::endl;
56 for (const auto& filename : command_line->GetArgs()) {
58 if (!base::ReadFileToString(base::FilePath(filename), &src)) {
59 std::cout << "# could not read " << filename << std::endl;
63 int64_t total_time = 0;
64 std::string error_message;
65 for (int i = 0; i < iterations; ++i) {
66 auto start = base::ThreadTicks::Now();
67 auto v = base::JSONReader::ReadAndReturnValueWithError(src);
68 auto end = base::ThreadTicks::Now();
69 int64_t iteration_time = (end - start).InMicroseconds();
70 total_time += iteration_time;
75 !v.has_value() ? std::move(v.error().message) : std::string();
77 std::cout << "# " << filename;
78 if (!v.has_value() && !v.error().message.empty()) {
79 std::cout << ": " << v.error().message;
81 std::cout << std::endl;
86 std::cout << iteration_time << std::endl;
91 int64_t average_time = total_time / iterations;
92 std::cout << std::setw(12) << average_time << "\t# " << filename;
93 if (!error_message.empty()) {
94 std::cout << ": " << error_message;
96 std::cout << std::endl;