• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef _KOALA_PROFILER_
17 #define _KOALA_PROFILER_
18 
19 #include <stdint.h>
20 #include <stdio.h>
21 
22 #include <unordered_map>
23 #include <string>
24 #include <vector>
25 #include <chrono>
26 #include <algorithm>
27 
28 constexpr double PERCENTAGE_FACTOR = 100.0;
29 
30 struct InteropProfilerRecord {
31     int64_t time;
32     int64_t count;
InteropProfilerRecordInteropProfilerRecord33     InteropProfilerRecord(int64_t time, int64_t count) : time(time), count(count) {}
34 };
35 
36 class InteropProfiler {
37   private:
38     std::unordered_map<std::string, InteropProfilerRecord> records;
39     static InteropProfiler* _instance;
InteropProfiler()40     InteropProfiler() {}
41 
42   public:
instance()43     static InteropProfiler* instance() {
44         if (!_instance) _instance = new InteropProfiler();
45         return _instance;
46     }
47 
record(const char * name,int64_t ns)48     void record(const char* name, int64_t ns) {
49         auto it = records.find(name);
50         if (it == records.end()) {
51             records.insert({name, InteropProfilerRecord(ns, 1)});
52         } else {
53             it->second.time += ns;
54             it->second.count++;
55         }
56     }
57 
report()58     std::string report() {
59         std::vector<std::pair<std::string, InteropProfilerRecord>> elems(records.begin(), records.end());
60         std::sort(elems.begin(), elems.end(),
61             [](const std::pair<std::string, InteropProfilerRecord>&a, const std::pair<std::string, InteropProfilerRecord>&b) {
62                 return b.second.time < a.second.time;
63             });
64         int64_t total = 0;
65         std::for_each(elems.begin(), elems.end(), [&total](const std::pair<std::string, InteropProfilerRecord>&a) {
66             total += a.second.time;
67         });
68         std::string result;
69         std::for_each(elems.begin(), elems.end(), [total, &result](const std::pair<std::string, InteropProfilerRecord>&a) {
70             auto ns = a.second.time;
71             auto count = a.second.count;
72             char buffer[1024];
73 #ifdef __STDC_LIB_EXT1__
74             errno_t res = snprintf_s(buffer, sizeof buffer, "for %s[%lld]: %.01f%% (%lld)\n", a.first.c_str(),
75                 (long long)count, (double)ns / total * PERCENTAGE_FACTOR, (long long)ns);
76             if (res != EOK) {
77                 return "";
78             }
79 #else
80             snprintf(buffer, sizeof buffer, "for %s[%lld]: %.01f%% (%lld)\n", a.first.c_str(),
81                 (long long)count, (double)ns / total * PERCENTAGE_FACTOR, (long long)ns);
82 #endif
83             result += buffer;
84         });
85         return result;
86     }
87 
reset()88     void reset() {
89         records.clear();
90     }
91 };
92 
93 
94 class InteropMethodCall {
95   private:
96     const char* name;
97     std::chrono::steady_clock::time_point begin;
98   public:
InteropMethodCall(const char * name)99     InteropMethodCall(const char* name) : name(name) {
100         begin = std::chrono::steady_clock::now();
101     }
~InteropMethodCall()102     ~InteropMethodCall() {
103         auto end = std::chrono::steady_clock::now();
104         int64_t ns = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count();
105         InteropProfiler::instance()->record(name, ns);
106     }
107 };
108 
109 #endif // _KOALA_PROFILER_