| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // Some portions Copyright (c) 2009 The Chromium Authors. | |
| 5 // | 4 // |
| 6 // Simple microbenchmark framework | 5 // Simple microbenchmark framework |
| 7 | 6 |
| 8 #ifndef __CHROMEOS_MICROBENCHMARK_MICROBENCHMARK_H | 7 #ifndef __CHROMEOS_MICROBENCHMARK_MICROBENCHMARK_H |
| 9 #define __CHROMEOS_MICROBENCHMARK_MICROBENCHMARK_H | 8 #define __CHROMEOS_MICROBENCHMARK_MICROBENCHMARK_H |
| 10 | 9 |
| 11 #include <errno.h> | 10 #include <errno.h> |
| 12 #include <time.h> | 11 #include <time.h> |
| 13 | 12 |
| 14 #include <iostream> | 13 #include <iostream> |
| 15 | 14 |
| 16 #include <base/basictypes.h> | 15 #include <base/basictypes.h> |
| 17 #include <base/command_line.h> | 16 #include <base/command_line.h> |
| 18 #include <base/logging.h> | 17 #include <base/logging.h> |
| 19 #include <base/scoped_ptr.h> | 18 #include <base/scoped_ptr.h> |
| 20 #include <gtest/gtest.h> | 19 #include <gtest/gtest.h> |
| 21 | 20 |
| 21 // CHROMEOS_MICROBENCHMARK_WITH_SETUP is the primary macro for |
| 22 // using a microbenchmark from this framework. |
| 23 // |
| 24 // For quick use, create a new .cc file in your project. |
| 25 // Include this header and create two static functions, |
| 26 // one for setup and one for executing the test once. |
| 27 // After both are defined, append: |
| 28 // CHROMEOS_MICROBENCHMARK_WITH_SETUP(MySetup, MyTest, 100000) |
| 29 // The last argument is the default number of runs. This may |
| 30 // be overridden at run-time and, in the future, may be automatically |
| 31 // tweaked to avoid measurement errors. |
| 32 // |
| 33 // The _NAME function should be of the prototype: |
| 34 // void MyTest(bool scaffold_only); |
| 35 // The _SETUP_NAME function should be of the prototype: |
| 36 // void SetupMyTest(uint64 number_of_runs); |
| 22 #define CHROMEOS_MICROBENCHMARK_WITH_SETUP(_SETUP_NAME, _NAME, _RUNS) \ | 37 #define CHROMEOS_MICROBENCHMARK_WITH_SETUP(_SETUP_NAME, _NAME, _RUNS) \ |
| 23 class _NAME ## Class : public Microbenchmark { \ | 38 class _NAME ## Class : public Microbenchmark { \ |
| 24 public: \ | 39 public: \ |
| 25 _NAME ## Class() {} \ | 40 _NAME ## Class() {} \ |
| 26 ~_NAME ## Class() {} \ | 41 ~_NAME ## Class() {} \ |
| 27 const char *name() const { return #_NAME; } \ | 42 const char *name() const { return #_NAME; } \ |
| 28 void Setup(uint64 runs) { _SETUP_NAME(runs); } \ | 43 void Setup(uint64 runs) { _SETUP_NAME(runs); } \ |
| 29 void SingleTest(bool scaffold_only) { _NAME(scaffold_only); } \ | 44 void SingleTest(bool scaffold_only) { _NAME(scaffold_only); } \ |
| 30 }; \ | 45 }; \ |
| 31 TEST(_NAME, Microbenchmark) { \ | 46 TEST(_NAME, Microbenchmark) { \ |
| 32 _NAME ## Class chromeos_benchmark; \ | 47 _NAME ## Class chromeos_benchmark; \ |
| 33 CommandLine *cl = CommandLine::ForCurrentProcess(); \ | 48 CommandLine *cl = CommandLine::ForCurrentProcess(); \ |
| 34 errno = 0; \ | 49 errno = 0; \ |
| 35 std::string runs_str = \ | 50 std::string runs_str = \ |
| 36 cl->GetSwitchValueASCII(chromeos::Microbenchmark::kRunsSwitch); \ | 51 cl->GetSwitchValueASCII(chromeos::Microbenchmark::kRunsSwitch); \ |
| 37 unsigned long long runs = _RUNS; \ | 52 unsigned long long runs = _RUNS; \ |
| 38 if (!runs_str.empty()) { \ | 53 if (!runs_str.empty()) { \ |
| 39 errno = 0; \ | 54 errno = 0; \ |
| 40 runs = strtoull(runs_str.c_str(), NULL, 0); \ | 55 runs = strtoull(runs_str.c_str(), NULL, 0); \ |
| 41 if (errno) \ | 56 if (errno) \ |
| 42 runs = _RUNS; \ | 57 runs = _RUNS; \ |
| 43 } \ | 58 } \ |
| 44 chromeos_benchmark.Run(runs); \ | 59 chromeos_benchmark.Run(runs); \ |
| 45 chromeos_benchmark.Print(); \ | 60 chromeos_benchmark.Print(); \ |
| 46 } | 61 } |
| 47 | 62 |
| 63 // This is a shortcut macro. If you don't need to setup any global state for |
| 64 // use in your test, you can use this instead of _WITH_SETUP. |
| 48 #define CHROMEOS_MICROBENCHMARK(_NAME, _RUNS) \ | 65 #define CHROMEOS_MICROBENCHMARK(_NAME, _RUNS) \ |
| 49 CHROMEOS_MICROBENCHMARK_WITH_SETUP(chromeos::microbenchmark_helper::NoSetup, \ | 66 CHROMEOS_MICROBENCHMARK_WITH_SETUP(chromeos::microbenchmark_helper::NoSetup, \ |
| 50 _NAME, \ | 67 _NAME, \ |
| 51 _RUNS) | 68 _RUNS) |
| 52 namespace chromeos { | 69 namespace chromeos { |
| 53 | 70 |
| 54 namespace microbenchmark_helper { | 71 namespace microbenchmark_helper { |
| 55 void NoSetup(uint64 runs); | 72 void NoSetup(uint64 runs); |
| 56 } // microbenchmark | 73 } // microbenchmark_helper |
| 57 | 74 |
| 58 // A simple microbenchmarking abstract class. | 75 // A simple microbenchmarking abstract class. |
| 59 // This class is not thread-safe and should only be invoked | 76 // This class is not thread-safe and should only be invoked |
| 60 // from one thread at a time. | 77 // from one thread at a time. |
| 61 class Microbenchmark { | 78 class Microbenchmark { |
| 62 public: | 79 public: |
| 63 Microbenchmark() : scaffold_total_ns_(0), | 80 Microbenchmark() : scaffold_total_ns_(0), |
| 64 scaffold_per_run_ns_(0), | 81 scaffold_per_run_ns_(0), |
| 65 total_ns_(0), | 82 total_ns_(0), |
| 66 per_run_ns_(0), | 83 per_run_ns_(0), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 92 uint64 scaffold_total_ns_; | 109 uint64 scaffold_total_ns_; |
| 93 uint64 scaffold_per_run_ns_; | 110 uint64 scaffold_per_run_ns_; |
| 94 uint64 total_ns_; | 111 uint64 total_ns_; |
| 95 uint64 per_run_ns_; | 112 uint64 per_run_ns_; |
| 96 uint64 runs_; | 113 uint64 runs_; |
| 97 DISALLOW_COPY_AND_ASSIGN(Microbenchmark); | 114 DISALLOW_COPY_AND_ASSIGN(Microbenchmark); |
| 98 }; | 115 }; |
| 99 | 116 |
| 100 } // chromeos | 117 } // chromeos |
| 101 #endif // __CHROMEOS_MICROBENCHMARK_MICROBENCHMARK_H | 118 #endif // __CHROMEOS_MICROBENCHMARK_MICROBENCHMARK_H |
| OLD | NEW |