xref: /aosp_15_r20/external/cronet/base/json/json_perftest_decodebench.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker // This program measures the time taken to decode the given JSON files (the
6*6777b538SAndroid Build Coastguard Worker // command line arguments). It is for manual benchmarking.
7*6777b538SAndroid Build Coastguard Worker //
8*6777b538SAndroid Build Coastguard Worker // Usage:
9*6777b538SAndroid Build Coastguard Worker // $ ninja -C out/foobar json_perftest_decodebench
10*6777b538SAndroid Build Coastguard Worker // $ out/foobar/json_perftest_decodebench -a -n=10 the/path/to/your/*.json
11*6777b538SAndroid Build Coastguard Worker //
12*6777b538SAndroid Build Coastguard Worker // The -n=10 switch controls the number of iterations. It defaults to 1.
13*6777b538SAndroid Build Coastguard Worker //
14*6777b538SAndroid Build Coastguard Worker // The -a switch means to print 1 non-comment line per input file (the average
15*6777b538SAndroid Build Coastguard Worker // iteration time). Without this switch (the default), it prints n non-comment
16*6777b538SAndroid Build Coastguard Worker // lines per input file (individual iteration times). For a single input file,
17*6777b538SAndroid Build Coastguard Worker // building and running this program before and after a particular commit can
18*6777b538SAndroid Build Coastguard Worker // work well with the 'ministat' tool: https://github.com/thorduri/ministat
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker #include <inttypes.h>
21*6777b538SAndroid Build Coastguard Worker #include <iomanip>
22*6777b538SAndroid Build Coastguard Worker #include <iostream>
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker #include "base/command_line.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/json/json_reader.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
29*6777b538SAndroid Build Coastguard Worker 
main(int argc,char * argv[])30*6777b538SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
31*6777b538SAndroid Build Coastguard Worker   if (!base::ThreadTicks::IsSupported()) {
32*6777b538SAndroid Build Coastguard Worker     std::cout << "# base::ThreadTicks is not supported\n";
33*6777b538SAndroid Build Coastguard Worker     return EXIT_FAILURE;
34*6777b538SAndroid Build Coastguard Worker   }
35*6777b538SAndroid Build Coastguard Worker   base::ThreadTicks::WaitUntilInitialized();
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker   base::CommandLine::Init(argc, argv);
38*6777b538SAndroid Build Coastguard Worker   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
39*6777b538SAndroid Build Coastguard Worker   bool average = command_line->HasSwitch("a");
40*6777b538SAndroid Build Coastguard Worker   int iterations = 1;
41*6777b538SAndroid Build Coastguard Worker   std::string iterations_str = command_line->GetSwitchValueASCII("n");
42*6777b538SAndroid Build Coastguard Worker   if (!iterations_str.empty()) {
43*6777b538SAndroid Build Coastguard Worker     iterations = atoi(iterations_str.c_str());
44*6777b538SAndroid Build Coastguard Worker     if (iterations < 1) {
45*6777b538SAndroid Build Coastguard Worker       std::cout << "# invalid -n command line switch\n";
46*6777b538SAndroid Build Coastguard Worker       return EXIT_FAILURE;
47*6777b538SAndroid Build Coastguard Worker     }
48*6777b538SAndroid Build Coastguard Worker   }
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   if (average) {
51*6777b538SAndroid Build Coastguard Worker     std::cout << "# Microseconds (μs), n=" << iterations << ", averaged"
52*6777b538SAndroid Build Coastguard Worker               << std::endl;
53*6777b538SAndroid Build Coastguard Worker   } else {
54*6777b538SAndroid Build Coastguard Worker     std::cout << "# Microseconds (μs), n=" << iterations << std::endl;
55*6777b538SAndroid Build Coastguard Worker   }
56*6777b538SAndroid Build Coastguard Worker   for (const auto& filename : command_line->GetArgs()) {
57*6777b538SAndroid Build Coastguard Worker     std::string src;
58*6777b538SAndroid Build Coastguard Worker     if (!base::ReadFileToString(base::FilePath(filename), &src)) {
59*6777b538SAndroid Build Coastguard Worker       std::cout << "# could not read " << filename << std::endl;
60*6777b538SAndroid Build Coastguard Worker       return EXIT_FAILURE;
61*6777b538SAndroid Build Coastguard Worker     }
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker     int64_t total_time = 0;
64*6777b538SAndroid Build Coastguard Worker     std::string error_message;
65*6777b538SAndroid Build Coastguard Worker     for (int i = 0; i < iterations; ++i) {
66*6777b538SAndroid Build Coastguard Worker       auto start = base::ThreadTicks::Now();
67*6777b538SAndroid Build Coastguard Worker       auto v = base::JSONReader::ReadAndReturnValueWithError(src);
68*6777b538SAndroid Build Coastguard Worker       auto end = base::ThreadTicks::Now();
69*6777b538SAndroid Build Coastguard Worker       int64_t iteration_time = (end - start).InMicroseconds();
70*6777b538SAndroid Build Coastguard Worker       total_time += iteration_time;
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker       if (i == 0) {
73*6777b538SAndroid Build Coastguard Worker         if (average) {
74*6777b538SAndroid Build Coastguard Worker           error_message =
75*6777b538SAndroid Build Coastguard Worker               !v.has_value() ? std::move(v.error().message) : std::string();
76*6777b538SAndroid Build Coastguard Worker         } else {
77*6777b538SAndroid Build Coastguard Worker           std::cout << "# " << filename;
78*6777b538SAndroid Build Coastguard Worker           if (!v.has_value() && !v.error().message.empty()) {
79*6777b538SAndroid Build Coastguard Worker             std::cout << ": " << v.error().message;
80*6777b538SAndroid Build Coastguard Worker           }
81*6777b538SAndroid Build Coastguard Worker           std::cout << std::endl;
82*6777b538SAndroid Build Coastguard Worker         }
83*6777b538SAndroid Build Coastguard Worker       }
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker       if (!average) {
86*6777b538SAndroid Build Coastguard Worker         std::cout << iteration_time << std::endl;
87*6777b538SAndroid Build Coastguard Worker       }
88*6777b538SAndroid Build Coastguard Worker     }
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker     if (average) {
91*6777b538SAndroid Build Coastguard Worker       int64_t average_time = total_time / iterations;
92*6777b538SAndroid Build Coastguard Worker       std::cout << std::setw(12) << average_time << "\t# " << filename;
93*6777b538SAndroid Build Coastguard Worker       if (!error_message.empty()) {
94*6777b538SAndroid Build Coastguard Worker         std::cout << ": " << error_message;
95*6777b538SAndroid Build Coastguard Worker       }
96*6777b538SAndroid Build Coastguard Worker       std::cout << std::endl;
97*6777b538SAndroid Build Coastguard Worker     }
98*6777b538SAndroid Build Coastguard Worker   }
99*6777b538SAndroid Build Coastguard Worker   return EXIT_SUCCESS;
100*6777b538SAndroid Build Coastguard Worker }
101