perf(async): remove unused sequence array and eliminate string copies#535
Conversation
The separate sequence_ array was redundant because each cell already contains its own atomic sequence number (cell::sequence) which is used by enqueue_impl() and dequeue(). The standalone array was initialized in the constructor but never read afterward, wasting Size * sizeof(std::atomic<size_t>) bytes per queue instance. Update the constructor to initialize cells_[i].sequence directly instead of the removed array. Closes #533
Pass to_string() rvalues directly to batch_entry constructor instead of storing them in intermediate local variables. The batch_entry constructor already accepts std::string by value and moves internally, so passing temporaries directly enables move semantics and avoids extra copies on each write() call. Closes #532
Add Performance entries to [Unreleased] section for unused sequence array removal and string copy elimination in hot path.
CI/CD Failure AnalysisAnalysis Time: 2026-03-20 11:00 KST Failed Workflows
Root Cause AnalysismacOS The CI workflow uses The Ubuntu PPA timeout (3 jobs): Workflows on Proposed Fix
Next Steps
Automated failure analysis - Attempt #1 |
The macos-14 runner image updated and clang++ now resolves to Homebrew LLVM Clang 15.0.7 instead of Apple Clang 15.0.0, which lacks std::format support. Use /usr/bin/clang(++) to ensure the system Apple Clang is used.
Performance Regression Check
Threshold: >5% regression triggers warning |
…#535) * perf(lockfree): remove unused sequence_ array from lockfree_spsc_queue The separate sequence_ array was redundant because each cell already contains its own atomic sequence number (cell::sequence) which is used by enqueue_impl() and dequeue(). The standalone array was initialized in the constructor but never read afterward, wasting Size * sizeof(std::atomic<size_t>) bytes per queue instance. Update the constructor to initialize cells_[i].sequence directly instead of the removed array. Closes #533 * perf(async): eliminate string copies in async writer hot path Pass to_string() rvalues directly to batch_entry constructor instead of storing them in intermediate local variables. The batch_entry constructor already accepts std::string by value and moves internally, so passing temporaries directly enables move semantics and avoids extra copies on each write() call. Closes #532 * docs: update CHANGELOG for #532, #533 Add Performance entries to [Unreleased] section for unused sequence array removal and string copy elimination in hot path. * fix(ci): use explicit Apple Clang path on macOS runners The macos-14 runner image updated and clang++ now resolves to Homebrew LLVM Clang 15.0.7 instead of Apple Clang 15.0.0, which lacks std::format support. Use /usr/bin/clang(++) to ensure the system Apple Clang is used.
What
Two performance improvements in the async logging pipeline:
sequence_array fromlockfree_spsc_queue(redundant withcells_[i].sequence)high_performance_async_writerhot pathChange Type
Affected Components
src/impl/async/lockfree_queue.h— Remove redundantsequence_arraysrc/impl/async/high_performance_async_writer.cpp— Constructbatch_entrydirectly with rvaluesWhy
sequence_array was a separatestd::array<std::atomic<size_t>, Size>that duplicated the per-cellsequencefield already present in thecellstruct — wasting cache linesstd::stringvariables for file, function names before passing tobatch_entryconstructor — unnecessary copies in a hot pathCloses #533
Closes #532
How
Implementation
alignas(cache_line_size) std::array<std::atomic<size_t>, Size> sequence_and updated initialization loop to usecells_[i].sequenceinsteadstd::stringvariables; passto_string()rvalues directly tobatch_entryconstructor for move semanticsTesting
batch_entryconstruction semantics unchanged (values moved, not copied)