!526 解析火焰图性能优化

Merge pull request !526 from yuanye/master
This commit is contained in:
openharmony_ci 2024-07-23 09:41:28 +00:00 committed by Gitee
commit d5a74a2c9a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 48 additions and 23 deletions

View File

@ -186,6 +186,7 @@ V &GetOrCreateMapItem(std::map<K, V> &map, const K &key)
struct ReportFuncMapItem {
int libId_ = -1;
std::string funcName_;
int reportFuncId_ = -1;
void OutputJson(FILE *output) const
{
if (fprintf(output, "{") < 0) {
@ -197,7 +198,8 @@ struct ReportFuncMapItem {
return;
}
}
ReportFuncMapItem(int libId, std::string &funcName) : libId_(libId), funcName_(funcName) {}
ReportFuncMapItem(int libId, std::string &funcName, int reportFuncId)
: libId_(libId), funcName_(funcName), reportFuncId_(reportFuncId) {}
};
struct ReportFuncItem {
@ -351,7 +353,6 @@ struct ReportConfigItem {
ReportConfigItem(int index, std::string eventName) : index_(index), eventName_(eventName) {}
};
using functionKey = std::tuple<int, std::string>;
static constexpr const int keyLibId = 0;
static constexpr const int keyfuncName = 1;
@ -381,9 +382,10 @@ private:
const std::unique_ptr<PerfFileReader> &recordFileReader_;
const VirtualRuntime &virtualRuntime_;
std::vector<std::string_view> libList_;
std::vector<functionKey> functionList_;
std::map<int, ReportFuncMapItem> functionMap_;
int functionId_ = 0;
std::map<int, std::map<std::string, ReportFuncMapItem>> functionMap_;
void AddNewFunction(int libId, std::string name);
void OutputJsonFunctionMap(FILE *output);
ReportConfigItem &GetConfig(uint64_t id);
std::string GetConfigName(uint64_t id);

View File

@ -27,10 +27,31 @@ namespace OHOS {
namespace Developtools {
namespace HiPerf {
bool ReportJsonFile::debug_ = false;
void ReportJsonFile::AddNewFunction(int libId, std::string name)
{
functionList_.emplace_back(functionKey(libId, name));
functionMap_.emplace(functionMap_.size(), ReportFuncMapItem(libId, name));
auto it = functionMap_.find(libId);
if (it == functionMap_.end()) {
it = functionMap_.try_emplace(libId).first;
}
it->second.insert_or_assign(name, ReportFuncMapItem(libId, name, functionId_++));
}
void ReportJsonFile::OutputJsonFunctionMap(FILE *output)
{
std::string key = "SymbolMap";
if (fprintf(output, "\"%s\":{", key.c_str()) != -1) {
bool first = true;
for (const auto& [libId, funcMap] : functionMap_) {
for (const auto& [_, reportFuncMapItem] : funcMap) {
OutputJsonPair(output, reportFuncMapItem.reportFuncId_, reportFuncMapItem, first);
first = false;
}
}
fprintf(output, "}");
}
}
void ReportJsonFile::ProcessSymbolsFiles(
@ -77,16 +98,19 @@ ReportConfigItem &ReportJsonFile::GetConfig(uint64_t id)
int ReportJsonFile::GetFunctionID(int libId, const std::string &function)
{
auto it = find(functionList_.begin(), functionList_.end(), functionKey(libId, function));
if (it != functionList_.end()) {
return it - functionList_.begin();
} else {
auto functionMapIt = functionMap_.find(libId);
if (functionMapIt == functionMap_.end()) {
functionMapIt = functionMap_.try_emplace(libId).first;
}
auto funcMapIt = functionMapIt->second.find(function);
if (funcMapIt == functionMapIt->second.end()) {
HLOGW("'%s' not found in function list in lib %d", function.data(), libId);
// make a new function for unknown name
AddNewFunction(libId, function);
// retuen the last index
return functionList_.size() >= 1 ? functionList_.size() - 1 : 0;
// return the last index
return functionId_ - 1;
}
return funcMapIt->second.reportFuncId_;
}
void ReportJsonFile::UpdateReportSample(uint64_t id, pid_t pid, pid_t tid, uint64_t eventCount)
@ -115,7 +139,7 @@ void ReportJsonFile::AddReportCallStack(uint64_t eventCount, ReportCallNodeItem
ReportCallNodeItem &grandchildren = GetOrCreateMapItem(*child, funcId);
if (debug_) {
grandchildren.nodeIndex_ = nodeIndex_++;
grandchildren.funcName_ = std::get<keyfuncName>(functionList_.at(funcId));
grandchildren.funcName_ = it->funcName;
grandchildren.reverseCaller_ = true;
}
// only the last one need count
@ -147,7 +171,7 @@ void ReportJsonFile::AddReportCallStackReverse(uint64_t eventCount, ReportCallNo
ReportCallNodeItem &grandchildren = GetOrCreateMapItem(*child, funcId);
if (debug_) {
grandchildren.nodeIndex_ = nodeIndex_++;
grandchildren.funcName_ = std::get<keyfuncName>(functionList_.at(funcId));
grandchildren.funcName_ = it->funcName;
}
// only the last one need count
if (it + 1 == frames.rend()) {
@ -296,7 +320,7 @@ void ReportJsonFile::OutputJsonRuntimeInfo()
return;
}
OutputJsonMap(output_, "SymbolMap", functionMap_, true);
OutputJsonFunctionMap(output_);
if (fprintf(output_, ",") < 0) {
return;
}

View File

@ -80,12 +80,10 @@ std::unique_ptr<ReportJsonFile> ReportJsonFileTest::PrepairReportJson(
json->reportConfigItems_.emplace(
ids, ReportConfigItem(json->reportConfigItems_.size(), "eventName"));
json->libList_ = {"liba", "libb", "libc"};
json->functionList_ = {
functionKey(0, "funca1"),
functionKey(0, "funca2"),
functionKey(1, "funcb1"),
functionKey(2, "funcc1"),
};
json->AddNewFunction(0, "funca1");
json->AddNewFunction(0, "funca2");
json->AddNewFunction(1, "funcb1");
json->AddNewFunction(2, "funcc1");
// id , pid , tid , event count
uint64_t id = 1;
uint64_t eventCount = 10;
@ -595,8 +593,9 @@ HWTEST_F(ReportJsonFileTest, ProcessSymbolsFiles, TestSize.Level1)
json->ProcessSymbolsFiles(symbolsFiles);
EXPECT_EQ(json->libList_.size(), 2u);
EXPECT_EQ(json->functionList_.size(), 5u);
EXPECT_EQ(json->functionMap_.size(), 5u);
ASSERT_EQ(json->functionMap_.size(), 2u);
EXPECT_EQ(json->functionMap_[0].size(), 2u);
EXPECT_EQ(json->functionMap_[1].size(), 3u);
}
/**