From 0bf3df28b9479583d045588341221c4bd67edc0b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 23 May 2021 23:01:11 +0200 Subject: [PATCH] LibDebug: Memoize resolved paths in DebugInfo::prepare_lines() When loading debug info, we encounter the same filename over and over (since files usually have many lines!) and we were wasting a ton of time re-checking if the filename was part of the Toolchain or libgcc, along with some other checks. This patch makes prepare_lines() significantly faster by memoizing the result of these checks per filename. This makes "bt 12" ~25% faster (from 850ms to 650ms on my machine.) :^) --- Userland/Libraries/LibDebug/DebugInfo.cpp | 32 ++++++++++++++--------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/Userland/Libraries/LibDebug/DebugInfo.cpp b/Userland/Libraries/LibDebug/DebugInfo.cpp index a3b03cfebc..4af2ea5c09 100644 --- a/Userland/Libraries/LibDebug/DebugInfo.cpp +++ b/Userland/Libraries/LibDebug/DebugInfo.cpp @@ -90,20 +90,28 @@ void DebugInfo::prepare_lines() all_lines.append(program.lines()); } - String serenity_slash("serenity/"); + HashMap> memoized_full_paths; + auto compute_full_path = [&](FlyString const& file_path) -> Optional { + if (file_path.view().contains("Toolchain/"sv) || file_path.view().contains("libgcc"sv)) + return {}; + if (file_path.view().starts_with("./"sv) && !m_source_root.is_null()) + return LexicalPath::join(m_source_root, file_path).string(); + if (auto index_of_serenity_slash = file_path.view().find("serenity/"sv); index_of_serenity_slash.has_value()) { + auto start_index = index_of_serenity_slash.value() + "serenity/"sv.length(); + return file_path.view().substring_view(start_index, file_path.length() - start_index); + } + return file_path; + }; - for (auto& line_info : all_lines) { - String file_path = line_info.file; - if (file_path.contains("Toolchain/") || file_path.contains("libgcc")) + for (auto const& line_info : all_lines) { + auto it = memoized_full_paths.find(line_info.file); + if (it == memoized_full_paths.end()) { + memoized_full_paths.set(line_info.file, compute_full_path(line_info.file)); + it = memoized_full_paths.find(line_info.file); + } + if (!it->value.has_value()) continue; - if (file_path.contains(serenity_slash)) { - auto start_index = file_path.index_of(serenity_slash).value() + serenity_slash.length(); - file_path = file_path.substring(start_index, file_path.length() - start_index); - } - if (file_path.starts_with("./") && !m_source_root.is_null()) { - file_path = LexicalPath::canonicalized_path(String::formatted("{}/{}", m_source_root, file_path)); - } - m_sorted_lines.append({ line_info.address, file_path, line_info.line }); + m_sorted_lines.append({ line_info.address, it->value.value(), line_info.line }); } quick_sort(m_sorted_lines, [](auto& a, auto& b) { return a.address < b.address;