Repository navigation
Inline frequently used parsing functions - #742
Merged
Merged
Conversation
Collaborator
|
Thanks for the contribution! This is excellent! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reading arrays of structs can leave a chain of small parser calls out of line in optimized builds without LTO. Add explicit inlining hints to eleven frequently used parsing declarations so the compiler can optimize field assignment, result handling, and object construction together.
LTO can eliminate much of the same parser-call overhead automatically. Separate Cereal measurements with #738–#741 applied reduced read time from 35.51 ms to 14.84 ms by enabling LTO alone, without this patch. Those measurements used a different dataset from the table below. This PR targets builds without LTO.
The change covers shared struct/vector parsing, field assignment, missing-field handling, the C++20 rvalue
Result::transformoverload, and two Cereal reader methods.RFL_ALWAYS_INLINEselects__forceinlinefor MSVC,inline __attribute__((always_inline))for GCC/Clang, and ordinaryinlineotherwise. Parsing logic, validation, error aggregation, cleanup, and the wire format are unchanged.Benchmarks
Add six
parser_inliningread cases toreflect-cpp-all-format-benchmarksand the Linux/macOS/Windows benchmark summaries. Each case reads a vector of 100,000 records with either two or sixteenfloatfields using ordinary APIs. Input generation, serialization, and equality checks happen outside timing; result destruction is included.AppleClang 21, macOS arm64, Release
-O3 -DNDEBUG, no LTO. Values are median CPU times from six alternating-order runs, with 0.1 s warmup and a 0.2 s measurement target per case. Both variants useed67735; the after variant adds only this PR. None of #739–#741 is included in these measurements.All six fixtures have byte-identical before/after output, and the patched reader successfully decodes the baseline fixtures. These are local microbenchmarks; gains depend on the compiler and input structure.
Compile time and code size
Compile each format's benchmark translation unit (both record widths) independently, without PCH or linking. Median CPU time from three alternating runs after a warmup:
__TEXTchangeThese measurements cover three translation units, not a full build. Small timing differences can be noise; larger schemas and other compilers may behave differently. Object
__TEXTincludes code and read-only data, not the final executable size.Validation
-O0 -g -Wall -Werrorsmoke test passes for recursive types, multiple validation errors, and truncated input.Run the new benchmarks with:
I got to the point where I made most clean optimizations for reflectcpp+Cereal vs raw Cereal speedup. I need to do few more tests, but currently it still reads 2.1x slower and writes 1.2x slower.
Later I will be able to share more complex data structure with benchmarks.