1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "MethodStatistics.h"
20 #include <chrono>
21 #include <memory>
22 #include <string>
23 #include <utility>
24 
25 namespace android::mediautils {
26 
27 class ScopedStatistics {
28   public:
29     /**
30      * ScopedStatistics is a RAII way of obtaining
31      * execution time statistics for a scoped C++ block.
32      *
33      * It updates the MethodStatistics shared pointer parameter
34      * with the methodName parameter and the duration/lifetime of the
35      * ScopedStatistics object.
36      *
37      * Not thread-safe, but expected to run in a single execution
38      * thread, and there are no user serviceable parts exposed.
39      *
40      * Example:
41      *
42      * std::shared_ptr<mediautils::MethodStatistics<std::string>> stats =
43      *     std::make_shared<mediautils::MethodStatistics<std::string>>();
44      *
45      * // ...
46      * {
47      *    mediautils::ScopedStatistics scopedStatistics("MyClass:myMethod", stats);
48      *
49      *    // some work to be timed here - up to the end of the block.
50      * }
51      *
52      * \param methodName the methodname to use "ClassName::methodName"
53      * \param statistics a shared ptr to the MethodStatistics object to use.
54      */
ScopedStatistics(std::string methodName,std::shared_ptr<mediautils::MethodStatistics<std::string>> statistics)55     ScopedStatistics(std::string methodName,
56                std::shared_ptr<mediautils::MethodStatistics<std::string>> statistics)
57         : mMethodName{std::move(methodName)}
58         , mStatistics{std::move(statistics)}
59         , mBegin{std::chrono::steady_clock::now()} {}
60 
61     // No copy constructor.
62     ScopedStatistics(const ScopedStatistics& scopedStatistics) = delete;
63     ScopedStatistics& operator=(const ScopedStatistics& scopedStatistics) = delete;
64 
~ScopedStatistics()65     ~ScopedStatistics() {
66         if (mStatistics) {
67             const float elapsedMs = std::chrono::duration_cast<std::chrono::nanoseconds>(
68                                             std::chrono::steady_clock::now() - mBegin)
69                                             .count() *
70                                     1e-6; // ns to ms.
71             mStatistics->event(mMethodName, elapsedMs);
72         }
73     }
74 
75   private:
76     const std::string mMethodName;
77     const std::shared_ptr<mediautils::MethodStatistics<std::string>> mStatistics;
78     const std::chrono::steady_clock::time_point mBegin;
79 };
80 
81 } // namespace android::mediautils
82