Skip to content

Commit a69fc0a

Browse files
committed
DPL: avoid multiple linear searches when handling command line options
1 parent f4dbc08 commit a69fc0a

1 file changed

Lines changed: 23 additions & 2 deletions

File tree

Framework/Core/src/DeviceSpecHelpers.cxx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <cstdio>
1717
#include <cstdlib>
1818
#include <cstring>
19+
#include <string_view>
20+
#include <unordered_map>
1921
#include <unordered_set>
2022
#include <vector>
2123
#include "Framework/ChannelConfigurationPolicy.h"
@@ -1596,11 +1598,30 @@ void DeviceSpecHelpers::prepareArguments(bool defaultQuiet, bool defaultStopped,
15961598
}
15971599
};
15981600

1601+
// Fast path for an exact, unambiguously declared long name. An option can
1602+
// carry more than one long name, so index all of them. A name declared twice
1603+
// is mapped to nullptr, so that it falls back to find_nothrow() below and is
1604+
// reported as ambiguous, as it would be without this lookup table. Wildcard
1605+
// and short-only names simply miss and fall back as well.
1606+
std::unordered_map<std::string_view, const bpo::option_description*> odescByName;
1607+
odescByName.reserve(odesc.options().size());
1608+
for (auto const& optDesc : odesc.options()) {
1609+
auto [names, count] = optDesc->long_names();
1610+
for (size_t ni = 0; ni < count; ++ni) {
1611+
auto [it, inserted] = odescByName.try_emplace(names[ni], optDesc.get());
1612+
if (!inserted) {
1613+
it->second = nullptr;
1614+
}
1615+
}
1616+
}
15991617
for (const auto& varit : varmap) {
16001618
// find the option belonging to key, add if the option has been parsed
16011619
// and is not defaulted
1602-
const auto* description = odesc.find_nothrow(varit.first, false);
1603-
if (description == nullptr || varmap.count(varit.first) == 0) {
1620+
auto descIt = odescByName.find(varit.first);
1621+
const auto* description = (descIt != odescByName.end() && descIt->second != nullptr)
1622+
? descIt->second
1623+
: odesc.find_nothrow(varit.first, false);
1624+
if (description == nullptr) {
16041625
continue;
16051626
}
16061627

0 commit comments

Comments
 (0)