From 949ac38c186fa62df84d194efde641e1a577e637 Mon Sep 17 00:00:00 2001 From: Rex Schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Thu, 13 Jun 2024 16:24:22 +0200 Subject: [PATCH] [core] expmap performance improvement (#1626) * performance improvement of update_timestamp for large maps (tested with > 25 k entries) * monitoring_get_topics sample slightly improved to allow time updates of internal (large) expmaps in case of subsequent readings --- ecal/core/src/util/ecal_expmap.h | 29 ++++++++++--------- .../src/monitoring_get_topics.cpp | 8 +++-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/ecal/core/src/util/ecal_expmap.h b/ecal/core/src/util/ecal_expmap.h index 20b1ddaec5..028d255622 100644 --- a/ecal/core/src/util/ecal_expmap.h +++ b/ecal/core/src/util/ecal_expmap.h @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -278,15 +278,8 @@ namespace eCAL // Remove all elements from the cache void clear() { - // Assert method is never called when cache is empty - //assert(!_key_tracker.empty()); - auto it(_key_tracker.begin()); - - while (it != _key_tracker.end()) - { - _key_to_value.erase(it->second); // erase the element from the map - it = _key_tracker.erase(it); // erase the element from the list - } + _key_to_value.clear(); // erase all elements from the map + _key_tracker.clear(); // erase all elements from the list } private: @@ -294,11 +287,19 @@ namespace eCAL // Maybe pass the iterator instead of the key? or at least only get k once void update_timestamp(const Key& k) { - _key_tracker.erase(_key_to_value.at(k).second); - auto new_iterator = _key_tracker.emplace(_key_tracker.end(), std::make_pair(get_curr_time(), k)); - _key_to_value.at(k).second = new_iterator; - } + auto it_in_map = _key_to_value.find(k); + if (it_in_map != _key_to_value.end()) + { + auto& it_in_list = it_in_map->second.second; + // move the element to the end of the list + _key_tracker.splice(_key_tracker.end(), _key_tracker, it_in_list); + + // update the timestamp + it_in_list->first = get_curr_time(); + } + } + // Record a fresh key-value pair in the cache std::pair insert(const Key& k, const T& v) { diff --git a/samples/cpp/monitoring/monitoring_get_topics/src/monitoring_get_topics.cpp b/samples/cpp/monitoring/monitoring_get_topics/src/monitoring_get_topics.cpp index 7e7c5acdcf..b62fe3b6b3 100644 --- a/samples/cpp/monitoring/monitoring_get_topics/src/monitoring_get_topics.cpp +++ b/samples/cpp/monitoring/monitoring_get_topics/src/monitoring_get_topics.cpp @@ -1,6 +1,6 @@ /* ========================= eCAL LICENSE ================================= * - * Copyright (C) 2016 - 2019 Continental Corporation + * Copyright (C) 2016 - 2024 Continental Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,10 +23,11 @@ #include #include #include +#include int main(int argc, char **argv) { - int run(0), runs(1000); + int run(0), runs(10); std::chrono::steady_clock::time_point start_time; // initialize eCAL core API @@ -48,8 +49,8 @@ int main(int argc, char **argv) auto num_topics = topic_info_map.size(); auto diff_time = std::chrono::duration_cast(std::chrono::steady_clock::now() - start_time); std::cout << "GetTopics : " << static_cast(diff_time.count()) / runs << " ms" << " (" << num_topics << " topics)" << std::endl; - std::cout << std::endl; } + std::this_thread::sleep_for(std::chrono::milliseconds(500)); // GetTopicNames { @@ -66,6 +67,7 @@ int main(int argc, char **argv) std::cout << "GetTopicsNames : " << static_cast(diff_time.count()) / runs << " ms" << " (" << num_topics << " topics)" << std::endl; std::cout << std::endl; } + std::this_thread::sleep_for(std::chrono::milliseconds(500)); } // finalize eCAL API