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 Workerint 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