From 9560cc4ea61ebafbbf835256bc100e19c8960ae7 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Thu, 16 Jun 2016 12:03:34 +0200 Subject: [PATCH] utility: Added Tracer for collecting time measurements * define TRACING_ENABLED in utility/tracing.h to enable tracing * invoke TraceEvent by writing TRACE() at start of function or scope * provide an event name with TRACE("name") * press SPACE to show collected traces history and report with accumulated times --- src/lib/Application.cpp | 5 + src/lib/CMakeLists.txt | 2 + .../component/controller/CodeController.cpp | 19 ++ .../component/controller/GraphController.cpp | 21 ++ .../component/controller/SearchController.cpp | 3 + src/lib/data/PersistentStorage.cpp | 57 +++++- src/lib/data/Storage.cpp | 3 + .../fulltextsearch/FullTextSearchIndex.cpp | 5 +- src/lib/utility/logging/logging.h | 14 +- src/lib/utility/tracing.cpp | 183 ++++++++++++++++++ src/lib/utility/tracing.h | 82 ++++++++ src/lib_gui/qt/window/QtMainWindow.cpp | 9 + src/lib_gui/qt/window/QtMainWindow.h | 2 + src/lib_parser/data/parser/cxx/CxxParser.cpp | 5 + 14 files changed, 401 insertions(+), 9 deletions(-) create mode 100644 src/lib/utility/tracing.cpp create mode 100644 src/lib/utility/tracing.h diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 7999bf23..e804637b 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -7,6 +7,7 @@ #include "utility/messaging/type/MessageStatus.h" #include "utility/messaging/type/MessageShowStartScreen.h" #include "utility/scheduling/TaskScheduler.h" +#include "utility/tracing.h" #include "utility/UserPaths.h" #include "utility/Version.h" @@ -231,6 +232,8 @@ void Application::handleMessage(MessageFinishedParsing* message) void Application::handleMessage(MessageLoadProject* message) { + TRACE("app load project"); + FilePath projectSettingsFilePath(message->projectSettingsFilePath); if (projectSettingsFilePath.empty()) { @@ -279,6 +282,8 @@ void Application::handleMessage(MessageLoadProject* message) void Application::handleMessage(MessageRefresh* message) { + TRACE("app refresh"); + loadSettings(); if (message->uiOnly) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 9e762725..cb1a7086 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -316,6 +316,8 @@ add_files( utility/ScopedSwitcher.h utility/TimePoint.cpp utility/TimePoint.h + utility/tracing.cpp + utility/tracing.h utility/types.h utility/UserPaths.cpp utility/UserPaths.h diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 3fff78c2..a5a5f46b 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -4,6 +4,7 @@ #include "utility/messaging/type/MessageStatus.h" #include "utility/text/TextAccess.h" +#include "utility/tracing.h" #include "utility/utility.h" #include "utility/utilityString.h" @@ -28,6 +29,8 @@ const uint CodeController::s_lineRadius = 2; void CodeController::handleMessage(MessageActivateAll* message) { + TRACE("code all"); + std::vector errors; m_collection = m_storageAccess->getErrorTokenLocations(&errors); std::vector snippets = getSnippetsForCollection(m_collection); @@ -95,6 +98,8 @@ void CodeController::handleMessage(MessageActivateLocalSymbols* message) void CodeController::handleMessage(MessageActivateTokens* message) { + TRACE("code activate"); + CodeView* view = getView(); if (!message->keepContent()) @@ -150,6 +155,8 @@ void CodeController::handleMessage(MessageActivateTokens* message) void CodeController::handleMessage(MessageChangeFileView* message) { + TRACE("code change file"); + CodeView* view = getView(); switch (message->state) @@ -237,6 +244,8 @@ void CodeController::handleMessage(MessageScrollCode* message) void CodeController::handleMessage(MessageShowErrors* message) { + TRACE("code errors"); + std::vector errors; m_collection = m_storageAccess->getErrorTokenLocations(&errors); std::vector snippets = getSnippetsForCollection(m_collection); @@ -251,6 +260,8 @@ void CodeController::handleMessage(MessageShowErrors* message) void CodeController::handleMessage(MessageSearchFullText* message) { + TRACE("code fulltext"); + CodeView* view = getView(); view->clear(); @@ -262,6 +273,8 @@ void CodeController::handleMessage(MessageSearchFullText* message) void CodeController::handleMessage(MessageShowScope* message) { + TRACE("code scope"); + std::shared_ptr collection = m_storageAccess->getTokenLocationsForLocationIds(std::vector(1, message->scopeLocationId)); @@ -328,6 +341,8 @@ void CodeController::showContents(MessageBase* message) std::vector CodeController::getSnippetsForActiveTokenLocations( const TokenLocationCollection* collection, Id declarationId ) const { + TRACE(); + std::vector snippets; size_t definitionFileCount = 0; size_t declarationFileCount = 0; @@ -429,6 +444,8 @@ std::vector CodeController::getSnippetsForFile( std::shared_ptr activeTokenLocations, bool addTokenLocations ) const { + TRACE(); + std::shared_ptr textAccess = m_storageAccess->getFileContent(activeTokenLocations->getFilePath()); std::shared_ptr scopeLocations = std::make_shared(activeTokenLocations->getFilePath().str()); @@ -713,6 +730,8 @@ std::vector CodeController::getProjectDescription(TokenLocationFile void CodeController::addModificationTimes(std::vector& snippets) const { + TRACE(); + std::vector filePaths; for (const CodeSnippetParams& snippet : snippets) { diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index 25005bb0..dda0704e 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -3,6 +3,7 @@ #include #include "utility/logging/logging.h" +#include "utility/tracing.h" #include "utility/utility.h" #include "utility/utilityString.h" @@ -23,6 +24,8 @@ GraphController::~GraphController() void GraphController::handleMessage(MessageActivateAll* message) { + TRACE("graph all"); + m_activeNodeIds.clear(); m_activeEdgeIds.clear(); @@ -38,6 +41,8 @@ void GraphController::handleMessage(MessageActivateAll* message) void GraphController::handleMessage(MessageActivateTokens* message) { + TRACE("graph activate"); + if (message->isEdge || message->keepContent()) { m_activeEdgeIds = message->tokenIds; @@ -192,6 +197,8 @@ void GraphController::clear() void GraphController::createDummyGraphForTokenIds(const std::vector& tokenIds, const std::shared_ptr graph) { + TRACE(); + GraphView* view = getView(); if (!view) { @@ -361,6 +368,8 @@ void GraphController::autoExpandActiveNode(const std::vector& activeTokenIds bool GraphController::setActive(const std::vector& activeTokenIds) { + TRACE(); + bool noActive = activeTokenIds.size() == 0; if (activeTokenIds.size() > 0) { @@ -401,6 +410,8 @@ bool GraphController::setActive(const std::vector& activeTokenIds) void GraphController::setVisibility(bool noActive) { + TRACE(); + for (std::shared_ptr node : m_dummyNodes) { removeImplicitChildrenRecursive(node.get()); @@ -411,6 +422,8 @@ void GraphController::setVisibility(bool noActive) void GraphController::setActiveAndVisibility(const std::vector& activeTokenIds) { + TRACE(); + setVisibility(setActive(activeTokenIds)); } @@ -519,6 +532,8 @@ void GraphController::setNodeVisibilityRecursiveTopDown(DummyNode* node, bool pa void GraphController::bundleNodes() { + TRACE(); + // evaluate top level nodes for (std::shared_ptr node : m_dummyNodes) { @@ -817,6 +832,8 @@ void GraphController::bundleNodesMatching( void GraphController::bundleNodesByType() { + TRACE(); + std::vector> oldNodes = m_dummyNodes; m_dummyNodes.clear(); @@ -864,6 +881,8 @@ void GraphController::bundleNodesByType() void GraphController::layoutNesting() { + TRACE(); + for (std::shared_ptr node : m_dummyNodes) { layoutNestingRecursive(node.get()); @@ -1096,6 +1115,8 @@ void GraphController::layoutToGrid(DummyNode* node) const void GraphController::layoutGraph(bool sort) { + TRACE(); + BucketGrid grid(getView()->getViewSize()); grid.createBuckets(m_dummyNodes, m_dummyEdges); diff --git a/src/lib/component/controller/SearchController.cpp b/src/lib/component/controller/SearchController.cpp index 1de18c68..6084891a 100644 --- a/src/lib/component/controller/SearchController.cpp +++ b/src/lib/component/controller/SearchController.cpp @@ -2,6 +2,7 @@ #include "component/view/SearchView.h" #include "data/access/StorageAccess.h" +#include "utility/tracing.h" SearchController::SearchController(StorageAccess* storageAccess) : m_storageAccess(storageAccess) @@ -59,6 +60,8 @@ void SearchController::handleMessage(MessageFind* message) void SearchController::handleMessage(MessageSearchAutocomplete* message) { + TRACE("search autocomplete"); + LOG_INFO("autocomplete string: \"" + message->query + "\""); getView()->setAutocompletionList(m_storageAccess->getAutocompletionMatches(message->query)); } diff --git a/src/lib/data/PersistentStorage.cpp b/src/lib/data/PersistentStorage.cpp index 0da1ffd6..bc28c7d8 100644 --- a/src/lib/data/PersistentStorage.cpp +++ b/src/lib/data/PersistentStorage.cpp @@ -3,6 +3,7 @@ #include #include +#include "utility/Cache.h" #include "utility/file/FileSystem.h" #include "utility/logging/logging.h" #include "utility/messaging/type/MessageClearErrorCount.h" @@ -10,10 +11,10 @@ #include "utility/messaging/type/MessageStatus.h" #include "utility/text/TextAccess.h" #include "utility/TimePoint.h" +#include "utility/tracing.h" #include "utility/utility.h" #include "utility/utilityString.h" #include "utility/Version.h" -#include "utility/Cache.h" #include "utility/utilityString.h" #include "data/graph/token_component/TokenComponentAggregation.h" @@ -265,6 +266,8 @@ void PersistentStorage::clearCaches() std::set PersistentStorage::getDependingFilePaths(const std::set& filePaths) { + TRACE(); + std::set dependingFilePaths; for (const FilePath& filePath: filePaths) { @@ -295,6 +298,8 @@ std::set PersistentStorage::getDependingFilePaths(const FilePath& file void PersistentStorage::clearFileElements(const std::vector& filePaths) { + TRACE(); + std::vector fileNodeIds; for (const FilePath& path : filePaths) @@ -313,6 +318,8 @@ void PersistentStorage::clearFileElements(const std::vector& filePaths std::vector PersistentStorage::getInfoOnAllFiles() const { + TRACE(); + std::vector fileInfos; std::vector storageFiles = m_sqliteStorage.getAllFiles(); @@ -334,6 +341,8 @@ std::vector PersistentStorage::getInfoOnAllFiles() const void PersistentStorage::logStats() const { + TRACE(); + std::stringstream ss; StorageStats stats = getStorageStats(); @@ -361,6 +370,8 @@ void PersistentStorage::startParsing() void PersistentStorage::finishParsing() { + TRACE(); + buildSearchIndex(); buildFilePathMaps(); buildHierarchyCache(); @@ -368,6 +379,8 @@ void PersistentStorage::finishParsing() void PersistentStorage::optimizeMemory() { + TRACE(); + m_sqliteStorage.optimizeMemory(); } @@ -399,6 +412,8 @@ std::shared_ptr PersistentStorage::getFullTextSearchLoc const std::string& searchTerm, bool caseSensitive ) const { + TRACE(); + if (m_fullTextSearchIndex.fileCount() == 0) { MessageStatus("Building fulltext search index", false, true).dispatch(); @@ -485,6 +500,8 @@ std::shared_ptr PersistentStorage::getFullTextSearchLoc std::vector PersistentStorage::getAutocompletionMatches(const std::string& query) const { + TRACE(); + std::vector commandResults = m_commandIndex.search(query, 0); const size_t maxResultCount = 100; @@ -638,6 +655,8 @@ std::vector PersistentStorage::getSearchMatchesForTokenIds(const st std::shared_ptr PersistentStorage::getGraphForAll() const { + TRACE(); + std::shared_ptr graph = std::make_shared(); std::vector tokenIds; @@ -658,6 +677,8 @@ std::shared_ptr PersistentStorage::getGraphForAll() const std::shared_ptr PersistentStorage::getGraphForActiveTokenIds(const std::vector& tokenIds) const { + TRACE(); + std::shared_ptr g = std::make_shared(); Graph* graph = g.get(); @@ -775,6 +796,8 @@ std::vector PersistentStorage::getActiveTokenIdsForId(Id tokenId, Id* declar std::vector PersistentStorage::getNodeIdsForLocationIds(const std::vector& locationIds) const { + TRACE(); + std::set edgeIds; std::set nodeIds; std::set implicitNodeIds; @@ -868,6 +891,8 @@ Id PersistentStorage::getTokenIdForFileNode(const FilePath& filePath) const std::shared_ptr PersistentStorage::getTokenLocationsForTokenIds( const std::vector& tokenIds) const { + TRACE(); + std::shared_ptr collection = std::make_shared(); std::vector fileIds; @@ -919,6 +944,8 @@ std::shared_ptr PersistentStorage::getTokenLocationsFor const std::vector& locationIds ) const { + TRACE(); + std::shared_ptr collection = std::make_shared(); for (size_t i = 0; i < locationIds.size(); i++) @@ -940,6 +967,8 @@ std::shared_ptr PersistentStorage::getTokenLocationsFor std::shared_ptr PersistentStorage::getTokenLocationsForFile(const std::string& filePath) const { + TRACE(); + return m_sqliteStorage.getTokenLocationsForFile(filePath); } @@ -947,11 +976,15 @@ std::shared_ptr PersistentStorage::getTokenLocationsForLinesI const std::string& filePath, uint firstLineNumber, uint lastLineNumber ) const { + TRACE(); + return getTokenLocationsForFile(filePath)->getFilteredByLines(firstLineNumber, lastLineNumber); } std::shared_ptr PersistentStorage::getErrorTokenLocations(std::vector* errors) const { + TRACE(); + std::shared_ptr errorCollection = std::make_shared(); std::vector storageErrors = m_sqliteStorage.getAllErrors(); @@ -969,6 +1002,8 @@ std::shared_ptr PersistentStorage::getErrorTokenLocatio std::shared_ptr PersistentStorage::getCommentLocationsInFile(const FilePath& filePath) const { + TRACE(); + std::shared_ptr file = std::make_shared(filePath); std::vector storageLocations = m_sqliteStorage.getCommentLocationsInFile(filePath); @@ -1017,6 +1052,8 @@ ErrorCountInfo PersistentStorage::getErrorCount() const StorageStats PersistentStorage::getStorageStats() const { + TRACE(); + StorageStats stats; stats.nodeCount = m_sqliteStorage.getNodeCount(); @@ -1083,6 +1120,8 @@ std::vector PersistentStorage::getAllChildNodeIds(const Id nodeId) const void PersistentStorage::addNodesToGraph(const std::vector& nodeIds, Graph* graph) const { + TRACE(); + if (nodeIds.size() == 0) { return; @@ -1127,6 +1166,8 @@ void PersistentStorage::addNodesToGraph(const std::vector& nodeIds, Graph* g void PersistentStorage::addEdgesToGraph(const std::vector& edgeIds, Graph* graph) const { + TRACE(); + if (edgeIds.size() == 0) { return; @@ -1153,6 +1194,8 @@ void PersistentStorage::addNodesWithChildrenAndEdgesToGraph( const std::vector& nodeIds, const std::vector& edgeIds, Graph* graph ) const { + TRACE(); + std::set parentNodeIds; for (Id nodeId : nodeIds) @@ -1185,6 +1228,8 @@ void PersistentStorage::addNodesWithChildrenAndEdgesToGraph( void PersistentStorage::addAggregationEdgesToGraph(const Id nodeId, Graph* graph) const { + TRACE(); + struct EdgeInfo { Id edgeId; @@ -1277,6 +1322,8 @@ void PersistentStorage::addAggregationEdgesToGraph(const Id nodeId, Graph* graph void PersistentStorage::addComponentAccessToGraph(Graph* graph) const { + TRACE(); + std::vector memberEdgeIds; graph->forEachEdge( @@ -1304,6 +1351,8 @@ void PersistentStorage::addComponentAccessToGraph(Graph* graph) const void PersistentStorage::buildSearchIndex() { + TRACE(); + for (StorageNode node: m_sqliteStorage.getAllNodes()) { m_elementIndex.addNode(node.id, NameHierarchy::deserialize(node.serializedName)); @@ -1313,6 +1362,8 @@ void PersistentStorage::buildSearchIndex() void PersistentStorage::buildFilePathMaps() { + TRACE(); + for (StorageFile file: m_sqliteStorage.getAllFiles()) { m_fileNodeIds.emplace(file.filePath, file.id); @@ -1322,6 +1373,8 @@ void PersistentStorage::buildFilePathMaps() void PersistentStorage::buildFullTextSearchIndex() const { + TRACE(); + for (StorageFile file : m_sqliteStorage.getAllFiles()) { m_fullTextSearchIndex.addFile(file.id, m_sqliteStorage.getFileContentById(file.id)->getText()); @@ -1330,6 +1383,8 @@ void PersistentStorage::buildFullTextSearchIndex() const void PersistentStorage::buildHierarchyCache() { + TRACE(); + std::vector memberEdges = m_sqliteStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_MEMBER)); Cache nodeTypeCache([this](Id id){ diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index a09b8a0d..0554f300 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -5,6 +5,7 @@ #include "data/graph/Edge.h" #include "data/StorageTypes.h" #include "utility/logging/logging.h" +#include "utility/tracing.h" Storage::Storage() { @@ -26,6 +27,8 @@ void Storage::finishInjection() void Storage::inject(Storage* injected) { + TRACE(); + startInjection(); std::unordered_map injectedIdToOwnId; diff --git a/src/lib/data/fulltextsearch/FullTextSearchIndex.cpp b/src/lib/data/fulltextsearch/FullTextSearchIndex.cpp index 0eba07d9..31fb9ccf 100644 --- a/src/lib/data/fulltextsearch/FullTextSearchIndex.cpp +++ b/src/lib/data/fulltextsearch/FullTextSearchIndex.cpp @@ -1,8 +1,9 @@ #include "data/fulltextsearch/FullTextSearchIndex.h" #include -#include "utility/utility.h" #include "utility/logging/logging.h" +#include "utility/tracing.h" +#include "utility/utility.h" void FullTextSearchIndex::addFile(Id fileId, const std::string& file) { @@ -22,6 +23,8 @@ void FullTextSearchIndex::addFile(Id fileId, const std::string& file) std::vector FullTextSearchIndex::searchForTerm(const std::string& term) const { + TRACE(); + std::vector ret; FullTextSearchResult hit; for (auto f : m_files) diff --git a/src/lib/utility/logging/logging.h b/src/lib/utility/logging/logging.h index 668eaa10..ee4fa075 100644 --- a/src/lib/utility/logging/logging.h +++ b/src/lib/utility/logging/logging.h @@ -13,21 +13,21 @@ { \ LogManager::getInstance()->logInfo(__str__, __FILE__, __FUNCTION__, __LINE__); \ } \ - while(0) \ + while(0) #define LOG_WARNING(__str__) \ do \ { \ LogManager::getInstance()->logWarning(__str__, __FILE__, __FUNCTION__, __LINE__); \ } \ - while(0) \ + while(0) #define LOG_ERROR(__str__) \ do \ { \ LogManager::getInstance()->logError(__str__, __FILE__, __FUNCTION__, __LINE__); \ } \ - while(0) \ + while(0) #define LOG_INFO_STREAM(__s__) \ do \ @@ -36,7 +36,7 @@ __ss__ __s__; \ LogManager::getInstance()->logInfo(__ss__.str(), __FILE__, __FUNCTION__, __LINE__); \ } \ - while(0) \ + while(0) #define LOG_WARNING_STREAM(__s__) \ do \ @@ -45,7 +45,7 @@ __ss__ __s__; \ LogManager::getInstance()->logWarning(__ss__.str(), __FILE__, __FUNCTION__, __LINE__); \ } \ - while(0) \ + while(0) #define LOG_ERROR_STREAM(__s__) \ do \ @@ -54,7 +54,7 @@ __ss__ __s__; \ LogManager::getInstance()->logError(__ss__.str(), __FILE__, __FUNCTION__, __LINE__); \ } \ - while(0) \ + while(0) #define LOG_INFO_STREAM_BARE(__s__) \ do \ @@ -63,6 +63,6 @@ __ss__ __s__; \ LogManager::getInstance()->logInfo(__ss__.str(), "", "", 0); \ } \ - while(0) \ + while(0) #endif // LOGGING_H diff --git a/src/lib/utility/tracing.cpp b/src/lib/utility/tracing.cpp new file mode 100644 index 00000000..58401099 --- /dev/null +++ b/src/lib/utility/tracing.cpp @@ -0,0 +1,183 @@ +#include "utility/tracing.h" + +#include "utility/utility.h" + +std::shared_ptr Tracer::s_instance; +Id Tracer::s_nextTraceId = 0; + +Tracer* Tracer::getInstance() +{ + if (!s_instance) + { + s_instance = std::shared_ptr(new Tracer()); + } + + return s_instance.get(); +} + +TraceEvent* Tracer::startEvent(const std::string& eventName) +{ + std::lock_guard lock(m_mutex); + + std::thread::id id = std::this_thread::get_id(); + std::shared_ptr event = + std::make_shared(eventName, s_nextTraceId++, m_startedEvents[id].size()); + + m_events[id].push_back(event); + m_startedEvents[id].push(event.get()); + + return event.get(); +} + +void Tracer::finishEvent(TraceEvent* event) +{ + std::lock_guard lock(m_mutex); + + std::thread::id id = std::this_thread::get_id(); + m_startedEvents[id].pop(); +} + +void Tracer::printTraces() +{ + std::lock_guard lock(m_mutex); + + size_t unfinishEvents = 0; + for (auto p : m_startedEvents) + { + unfinishEvents += p.second.size(); + } + + if (unfinishEvents > 0) + { + std::cout << "TRACING: Trace events are still running." << std::endl; + return; + } + else if (!m_events.size()) + { + std::cout << "TRACING: No trace events collected." << std::endl; + return; + } + + + std::cout << "TRACING\n--------------------------\n" << std::endl; + + std::cout << "HISTORY:\n\n"; + std::cout << " time name function"; + std::cout << " location\n"; + std::cout << "-----------------------------------------------------------------"; + std::cout << "------------------------------------------------------------\n"; + + for (auto p : m_events) + { + std::cout << "thread: " << p.first << std::endl; + + for (const std::shared_ptr event : p.second) + { + std::cout.width(8 + 2 * event->depth); + std::cout << std::right << std::setprecision(3) << std::fixed << event->time; + + std::cout.width(17 - 2 * event->depth); + std::cout << " "; + + std::cout.width(25); + std::cout << std::left << event->eventName; + + std::cout.width(50); + std::cout << (event->functionName + "()") << event->locationName << std::endl; + } + + std::cout << std::endl; + } + + std::cout << "\nREPORT:\n\n"; + std::cout << " time count name function"; + std::cout << " location\n"; + std::cout << "-----------------------------------------------------------------"; + std::cout << "------------------------------------------------------------\n"; + + struct AccumulatedTraceEvent + { + TraceEvent* event; + size_t count; + float time; + }; + + std::map accumulatedEvents; + + for (auto p : m_events) + { + for (const std::shared_ptr event : p.second) + { + std::string name = event->eventName + event->functionName + event->locationName; + + std::pair::iterator, bool> p = + accumulatedEvents.emplace(name, AccumulatedTraceEvent()); + + AccumulatedTraceEvent* acc = &p.first->second; + if (p.second) + { + acc->event = event.get(); + acc->time = event->time; + acc->count = 1; + } + else + { + acc->time += event->time; + acc->count++; + } + } + } + + std::multiset> sortedEvents( + [](const AccumulatedTraceEvent& a, const AccumulatedTraceEvent& b) + { + return a.time > b.time; + } + ); + + for (const std::pair p : accumulatedEvents) + { + sortedEvents.insert(p.second); + } + + for (const AccumulatedTraceEvent& acc : sortedEvents) + { + std::cout.width(8); + std::cout << std::right << std::setprecision(3) << std::fixed << acc.time; + + std::cout.width(10); + std::cout << acc.count << " "; + + std::cout.width(25); + std::cout << std::left << acc.event->eventName; + + std::cout.width(50); + std::cout << (acc.event->functionName + "()") << acc.event->locationName << std::endl; + } + + std::cout << std::endl; + + m_events.clear(); +} + +Tracer::Tracer() +{ +} + + +ScopedTrace::ScopedTrace( + const std::string& eventName, const std::string& fileName, int lineNumber, const std::string& functionName) +{ + m_event = Tracer::getInstance()->startEvent(eventName); + m_event->functionName = functionName; + m_event->locationName = FilePath(fileName).fileName() + ":" + std::to_string(lineNumber); + + m_timePoint = utility::durationStart(); +} + +ScopedTrace::~ScopedTrace() +{ + m_event->time = utility::duration(m_timePoint); + Tracer::getInstance()->finishEvent(m_event); +} diff --git a/src/lib/utility/tracing.h b/src/lib/utility/tracing.h new file mode 100644 index 00000000..7a0823ec --- /dev/null +++ b/src/lib/utility/tracing.h @@ -0,0 +1,82 @@ +#ifndef TRACING_H +#define TRACING_H + +#include +#include + +#include "utility/TimePoint.h" +#include "utility/types.h" + +struct TraceEvent +{ +public: + TraceEvent(const std::string& eventName, Id id, size_t depth) + : eventName(eventName) + , id(id) + , depth(depth) + , time(0.0f) + { + } + + const std::string eventName; + const Id id; + const size_t depth; + + std::string functionName; + std::string locationName; + + float time; +}; + + +class Tracer +{ +public: + static Tracer* getInstance(); + + TraceEvent* startEvent(const std::string& eventName); + void finishEvent(TraceEvent* event); + + void printTraces(); + +private: + static std::shared_ptr s_instance; + static Id s_nextTraceId; + + Tracer(); + Tracer(const Tracer&); + void operator=(const Tracer&); + + std::map>> m_events; + std::map> m_startedEvents; + + std::mutex m_mutex; +}; + + +class ScopedTrace +{ +public: + ScopedTrace(const std::string& eventName, const std::string& fileName, int lineNumber, const std::string& functionName); + ~ScopedTrace(); + +private: + TraceEvent* m_event; + TimePoint m_timePoint; +}; + + +// #define TRACING_ENABLED + +#ifdef TRACING_ENABLED + #define TRACE(__name__) \ + ScopedTrace __trace__(std::string(__name__), __FILE__, __LINE__, __FUNCTION__) + + #define PRINT_TRACES() \ + Tracer::getInstance()->printTraces() +#else + #define TRACE(__name__) + #define PRINT_TRACES() +#endif + +#endif // TRACING_H diff --git a/src/lib_gui/qt/window/QtMainWindow.cpp b/src/lib_gui/qt/window/QtMainWindow.cpp index 6795f885..903f6d18 100644 --- a/src/lib_gui/qt/window/QtMainWindow.cpp +++ b/src/lib_gui/qt/window/QtMainWindow.cpp @@ -37,6 +37,7 @@ #include "utility/messaging/type/MessageWindowFocus.h" #include "utility/messaging/type/MessageZoom.h" #include "utility/ResourcePaths.h" +#include "utility/tracing.h" #include "utility/UserPaths.h" #include "version.h" #include "isTrial.h" @@ -507,6 +508,11 @@ void QtMainWindow::handleEscapeShortcut() MessageInterruptTasks().dispatch(); } +void QtMainWindow::handleSpaceShortcut() +{ + PRINT_TRACES(); +} + void QtMainWindow::setupProjectMenu() { QMenu *menu = new QMenu(tr("&Project"), this); @@ -662,6 +668,9 @@ void QtMainWindow::setupShortcuts() { m_escapeShortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this); connect(m_escapeShortcut, SIGNAL(activated()), SLOT(handleEscapeShortcut())); + + m_spaceShortcut = new QShortcut(QKeySequence(Qt::Key_Space), this); + connect(m_spaceShortcut, SIGNAL(activated()), SLOT(handleSpaceShortcut())); } QtMainWindow::DockWidget* QtMainWindow::getDockWidgetForView(View* view) diff --git a/src/lib_gui/qt/window/QtMainWindow.h b/src/lib_gui/qt/window/QtMainWindow.h index aae64cc4..c2d81abf 100644 --- a/src/lib_gui/qt/window/QtMainWindow.h +++ b/src/lib_gui/qt/window/QtMainWindow.h @@ -131,6 +131,7 @@ public slots: void toggleView(View* view, bool fromMenu); void handleEscapeShortcut(); + void handleSpaceShortcut(); void updateRecentProjectMenu(); @@ -170,6 +171,7 @@ private: QtWindowStack m_windowStack; QShortcut* m_escapeShortcut; + QShortcut* m_spaceShortcut; }; #endif // QT_MAIN_WINDOW_H diff --git a/src/lib_parser/data/parser/cxx/CxxParser.cpp b/src/lib_parser/data/parser/cxx/CxxParser.cpp index 1693c5f8..4eecc327 100644 --- a/src/lib_parser/data/parser/cxx/CxxParser.cpp +++ b/src/lib_parser/data/parser/cxx/CxxParser.cpp @@ -5,6 +5,7 @@ #include "utility/file/FileRegister.h" #include "utility/logging/logging.h" #include "utility/text/TextAccess.h" +#include "utility/tracing.h" #include "data/parser/cxx/ASTActionFactory.h" #include "data/parser/cxx/CxxCompilationDatabaseSingle.h" @@ -195,6 +196,8 @@ void CxxParser::setupParsingCDB(const Arguments& arguments) void CxxParser::runTool(const std::vector& files) { + TRACE(); + clang::tooling::ClangTool tool(*m_compilationDatabase, files); tool.setDiagnosticConsumer(m_diagnostics.get()); @@ -204,6 +207,8 @@ void CxxParser::runTool(const std::vector& files) void CxxParser::runTool(clang::tooling::CompileCommand command, const Arguments& arguments) { + TRACE(); + std::vector args = getCommandlineArgumentsEssential(arguments); command.CommandLine.insert(command.CommandLine.end(), args.begin(), args.end());