mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
ifcparse: inline the file reader accessors and pre-size the inverse index
full_buffer_impl::size(), get(), get_u32() and get_u64() (and their mmap_impl twins) were defined out of line, so every character the lexer read crossed a call boundary with its own bounds check. Callgrind put the three at 5.6% of parse self time; inlining them lets the compiler hoist the checks out of the scanning loops, which is worth more than their own cost. Also reserve the streamer's inverse vector from the file size (about one record per 32 bytes of SPF on real models) and shrink it once the bulk load is sorted, so the doubling copies and the capacity slack go away. Parse time, C++ file constructor, 12-core Linux box: TXG 58 MB 1.35 s -> 1.15 s 210_King 148 MB 3.70 s -> 3.09 s OKgate22 232 MB 6.18 s -> 5.30 s Python ifcopenshell.open(): 1.40 -> 1.22, 3.70 -> 3.24, 6.27 -> 5.52 s. Memory unchanged. The removed exported symbols mean the Python wrapper must be rebuilt against this library. 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:
@@ -2412,6 +2412,9 @@ void ifcopenshell::impl::in_memory_file_storage::read_from_stream(Reader* s, con
|
||||
std::vector<std::string> schemas;
|
||||
|
||||
instance_streamer<Reader> streamer(s, file, logger_.get());
|
||||
// One inverse record per ~32 bytes of SPF text is a slight over-estimate on
|
||||
// real models; reserving avoids the doubling copies and the capacity slack.
|
||||
streamer.inverses().reserve(s->size() / 32);
|
||||
streamer.yield_header_instances(false);
|
||||
|
||||
if (const auto* header = streamer.header()) {
|
||||
|
||||
Reference in New Issue
Block a user