ifcparse: store the GlobalId index in a hash map with inline keys

byguid_ was a std::map<std::string, ...>: a red-black node plus a
heap-allocated 22-character string per rooted instance, and a lookup that
walks ~18 levels of string comparisons on a 200k-entry file.

guid_map keeps keys of up to 23 characters inline in an unordered_map node
(every valid GlobalId is 22), and routes anything longer to an ordered map
so invalid files still work. Same std::string-keyed interface as before.

Parse, C++ file constructor, on top of the previous commits:
  TXG            58 MB   1.08 s -> 1.03 s   341 -> 335 MB
  210_King      148 MB   2.80 s -> 2.72 s   836 -> 830 MB
  OKgate22      232 MB   4.25 s -> 3.94 s  1271 -> 1253 MB

This commit was written by an AI coding tool and has not been verified by
a human.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013wcN7XquTfUi4vsKQ4KchL
This commit is contained in:
Dion Moult
2026-09-11 16:17:18 +10:00
parent e0b6122d17
commit 64805b409f
6 changed files with 127 additions and 26 deletions
+8 -5
View File
@@ -2462,12 +2462,15 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
if (instance.declaration().is(*ifcroot_type_)) {
try {
const std::string guid = instance.get_attribute_value(0);
if (byguid_.find(guid) != byguid_.end()) {
std::stringstream ss;
ss << "Instance encountered with non-unique GlobalId " << guid;
logger_.get().message(ifcopenshell::logger::LOG_WARNING, ss.str());
std::array<char, 22> key;
if (guid_key(guid, key)) {
if (byguid_.count(key) != 0) {
std::stringstream ss;
ss << "Instance encountered with non-unique GlobalId " << guid;
logger_.get().message(ifcopenshell::logger::LOG_WARNING, ss.str());
}
byguid_[key] = instance;
}
byguid_[guid] = instance;
} catch (const exception& ex) {
logger_.get().message(ifcopenshell::logger::LOG_ERROR, ex.what());
}