From c2c82afb027d3f9d40398d14dfc87eadb1467203 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sun, 9 Aug 2026 16:57:54 +0200 Subject: [PATCH] DPL: avoid multiple linear searches when handling command line options --- Framework/Core/src/DeviceSpecHelpers.cxx | 25 ++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/Framework/Core/src/DeviceSpecHelpers.cxx b/Framework/Core/src/DeviceSpecHelpers.cxx index 64d0f58938941..4c19e7a6ff17b 100644 --- a/Framework/Core/src/DeviceSpecHelpers.cxx +++ b/Framework/Core/src/DeviceSpecHelpers.cxx @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include "Framework/ChannelConfigurationPolicy.h" @@ -1596,11 +1598,30 @@ void DeviceSpecHelpers::prepareArguments(bool defaultQuiet, bool defaultStopped, } }; + // Fast path for an exact, unambiguously declared long name. An option can + // carry more than one long name, so index all of them. A name declared twice + // is mapped to nullptr, so that it falls back to find_nothrow() below and is + // reported as ambiguous, as it would be without this lookup table. Wildcard + // and short-only names simply miss and fall back as well. + std::unordered_map odescByName; + odescByName.reserve(odesc.options().size()); + for (auto const& optDesc : odesc.options()) { + auto [names, count] = optDesc->long_names(); + for (size_t ni = 0; ni < count; ++ni) { + auto [it, inserted] = odescByName.try_emplace(names[ni], optDesc.get()); + if (!inserted) { + it->second = nullptr; + } + } + } for (const auto& varit : varmap) { // find the option belonging to key, add if the option has been parsed // and is not defaulted - const auto* description = odesc.find_nothrow(varit.first, false); - if (description == nullptr || varmap.count(varit.first) == 0) { + auto descIt = odescByName.find(varit.first); + const auto* description = (descIt != odescByName.end() && descIt->second != nullptr) + ? descIt->second + : odesc.find_nothrow(varit.first, false); + if (description == nullptr) { continue; }