1a8c51b3fSopenharmony_ci# Copyright 2020 Google Inc. All rights reserved.
2a8c51b3fSopenharmony_ci#
3a8c51b3fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
4a8c51b3fSopenharmony_ci# you may not use this file except in compliance with the License.
5a8c51b3fSopenharmony_ci# You may obtain a copy of the License at
6a8c51b3fSopenharmony_ci#
7a8c51b3fSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
8a8c51b3fSopenharmony_ci#
9a8c51b3fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
10a8c51b3fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
11a8c51b3fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a8c51b3fSopenharmony_ci# See the License for the specific language governing permissions and
13a8c51b3fSopenharmony_ci# limitations under the License.
14a8c51b3fSopenharmony_ci"""Example of Python using C++ benchmark framework.
15a8c51b3fSopenharmony_ci
16a8c51b3fSopenharmony_ciTo run this example, you must first install the `google_benchmark` Python package.
17a8c51b3fSopenharmony_ci
18a8c51b3fSopenharmony_ciTo install using `setup.py`, download and extract the `google_benchmark` source.
19a8c51b3fSopenharmony_ciIn the extracted directory, execute:
20a8c51b3fSopenharmony_ci  python setup.py install
21a8c51b3fSopenharmony_ci"""
22a8c51b3fSopenharmony_ci
23a8c51b3fSopenharmony_ciimport random
24a8c51b3fSopenharmony_ciimport time
25a8c51b3fSopenharmony_ci
26a8c51b3fSopenharmony_ciimport google_benchmark as benchmark
27a8c51b3fSopenharmony_cifrom google_benchmark import Counter
28a8c51b3fSopenharmony_ci
29a8c51b3fSopenharmony_ci
30a8c51b3fSopenharmony_ci@benchmark.register
31a8c51b3fSopenharmony_cidef empty(state):
32a8c51b3fSopenharmony_ci    while state:
33a8c51b3fSopenharmony_ci        pass
34a8c51b3fSopenharmony_ci
35a8c51b3fSopenharmony_ci
36a8c51b3fSopenharmony_ci@benchmark.register
37a8c51b3fSopenharmony_cidef sum_million(state):
38a8c51b3fSopenharmony_ci    while state:
39a8c51b3fSopenharmony_ci        sum(range(1_000_000))
40a8c51b3fSopenharmony_ci
41a8c51b3fSopenharmony_ci@benchmark.register
42a8c51b3fSopenharmony_cidef pause_timing(state):
43a8c51b3fSopenharmony_ci    """Pause timing every iteration."""
44a8c51b3fSopenharmony_ci    while state:
45a8c51b3fSopenharmony_ci        # Construct a list of random ints every iteration without timing it
46a8c51b3fSopenharmony_ci        state.pause_timing()
47a8c51b3fSopenharmony_ci        random_list = [random.randint(0, 100) for _ in range(100)]
48a8c51b3fSopenharmony_ci        state.resume_timing()
49a8c51b3fSopenharmony_ci        # Time the in place sorting algorithm
50a8c51b3fSopenharmony_ci        random_list.sort()
51a8c51b3fSopenharmony_ci
52a8c51b3fSopenharmony_ci
53a8c51b3fSopenharmony_ci@benchmark.register
54a8c51b3fSopenharmony_cidef skipped(state):
55a8c51b3fSopenharmony_ci    if True:  # Test some predicate here.
56a8c51b3fSopenharmony_ci        state.skip_with_error("some error")
57a8c51b3fSopenharmony_ci        return  # NOTE: You must explicitly return, or benchmark will continue.
58a8c51b3fSopenharmony_ci
59a8c51b3fSopenharmony_ci    ...  # Benchmark code would be here.
60a8c51b3fSopenharmony_ci
61a8c51b3fSopenharmony_ci
62a8c51b3fSopenharmony_ci@benchmark.register
63a8c51b3fSopenharmony_cidef manual_timing(state):
64a8c51b3fSopenharmony_ci    while state:
65a8c51b3fSopenharmony_ci        # Manually count Python CPU time
66a8c51b3fSopenharmony_ci        start = time.perf_counter()  # perf_counter_ns() in Python 3.7+
67a8c51b3fSopenharmony_ci        # Something to benchmark
68a8c51b3fSopenharmony_ci        time.sleep(0.01)
69a8c51b3fSopenharmony_ci        end = time.perf_counter()
70a8c51b3fSopenharmony_ci        state.set_iteration_time(end - start)
71a8c51b3fSopenharmony_ci
72a8c51b3fSopenharmony_ci
73a8c51b3fSopenharmony_ci@benchmark.register
74a8c51b3fSopenharmony_cidef custom_counters(state):
75a8c51b3fSopenharmony_ci    """Collect custom metric using benchmark.Counter."""
76a8c51b3fSopenharmony_ci    num_foo = 0.0
77a8c51b3fSopenharmony_ci    while state:
78a8c51b3fSopenharmony_ci        # Benchmark some code here
79a8c51b3fSopenharmony_ci        pass
80a8c51b3fSopenharmony_ci        # Collect some custom metric named foo
81a8c51b3fSopenharmony_ci        num_foo += 0.13
82a8c51b3fSopenharmony_ci
83a8c51b3fSopenharmony_ci    # Automatic Counter from numbers.
84a8c51b3fSopenharmony_ci    state.counters["foo"] = num_foo
85a8c51b3fSopenharmony_ci    # Set a counter as a rate.
86a8c51b3fSopenharmony_ci    state.counters["foo_rate"] = Counter(num_foo, Counter.kIsRate)
87a8c51b3fSopenharmony_ci    #  Set a counter as an inverse of rate.
88a8c51b3fSopenharmony_ci    state.counters["foo_inv_rate"] = Counter(num_foo, Counter.kIsRate | Counter.kInvert)
89a8c51b3fSopenharmony_ci    # Set a counter as a thread-average quantity.
90a8c51b3fSopenharmony_ci    state.counters["foo_avg"] = Counter(num_foo, Counter.kAvgThreads)
91a8c51b3fSopenharmony_ci    # There's also a combined flag:
92a8c51b3fSopenharmony_ci    state.counters["foo_avg_rate"] = Counter(num_foo, Counter.kAvgThreadsRate)
93a8c51b3fSopenharmony_ci
94a8c51b3fSopenharmony_ci
95a8c51b3fSopenharmony_ci@benchmark.register
96a8c51b3fSopenharmony_ci@benchmark.option.measure_process_cpu_time()
97a8c51b3fSopenharmony_ci@benchmark.option.use_real_time()
98a8c51b3fSopenharmony_cidef with_options(state):
99a8c51b3fSopenharmony_ci    while state:
100a8c51b3fSopenharmony_ci        sum(range(1_000_000))
101a8c51b3fSopenharmony_ci
102a8c51b3fSopenharmony_ci
103a8c51b3fSopenharmony_ci@benchmark.register(name="sum_million_microseconds")
104a8c51b3fSopenharmony_ci@benchmark.option.unit(benchmark.kMicrosecond)
105a8c51b3fSopenharmony_cidef with_options2(state):
106a8c51b3fSopenharmony_ci    while state:
107a8c51b3fSopenharmony_ci        sum(range(1_000_000))
108a8c51b3fSopenharmony_ci
109a8c51b3fSopenharmony_ci
110a8c51b3fSopenharmony_ci@benchmark.register
111a8c51b3fSopenharmony_ci@benchmark.option.arg(100)
112a8c51b3fSopenharmony_ci@benchmark.option.arg(1000)
113a8c51b3fSopenharmony_cidef passing_argument(state):
114a8c51b3fSopenharmony_ci    while state:
115a8c51b3fSopenharmony_ci        sum(range(state.range(0)))
116a8c51b3fSopenharmony_ci
117a8c51b3fSopenharmony_ci
118a8c51b3fSopenharmony_ci@benchmark.register
119a8c51b3fSopenharmony_ci@benchmark.option.range(8, limit=8 << 10)
120a8c51b3fSopenharmony_cidef using_range(state):
121a8c51b3fSopenharmony_ci    while state:
122a8c51b3fSopenharmony_ci        sum(range(state.range(0)))
123a8c51b3fSopenharmony_ci
124a8c51b3fSopenharmony_ci
125a8c51b3fSopenharmony_ci@benchmark.register
126a8c51b3fSopenharmony_ci@benchmark.option.range_multiplier(2)
127a8c51b3fSopenharmony_ci@benchmark.option.range(1 << 10, 1 << 18)
128a8c51b3fSopenharmony_ci@benchmark.option.complexity(benchmark.oN)
129a8c51b3fSopenharmony_cidef computing_complexity(state):
130a8c51b3fSopenharmony_ci    while state:
131a8c51b3fSopenharmony_ci        sum(range(state.range(0)))
132a8c51b3fSopenharmony_ci    state.complexity_n = state.range(0)
133a8c51b3fSopenharmony_ci
134a8c51b3fSopenharmony_ci
135a8c51b3fSopenharmony_ciif __name__ == "__main__":
136a8c51b3fSopenharmony_ci    benchmark.main()
137