CBOR reader: inline get_cbor_float() and always inline get() instead
The never-inlined get_cbor_float() costs a call for every float read from input without bulk access: reading canada.json from CBOR through a FILE* became 5.6 % slower on Apple clang in the benchmark suite. The helper existed only because GCC 13 stopped inlining the stream adapter's get_character() into parse_cbor_internal. Always inlining binary_reader::get() fixes that as well. callgrind, all binary formats on buffer, std::istringstream and FILE* input (canada and citm_catalog): GCC 13 0.986-1.003, GCC 16 0.994-1.006, Clang 23 identical. Apple clang suite: FromBinaryFile/cbor/canada 0.939, geomean of the 53 binary reader rows 0.998. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
2 files changed
+12
-6
No files matched your search
@@ -1148,10 +1148,8 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// read a single- or double-precision float (kept out of
|
/// read a single- or double-precision float
|
||||||
/// parse_cbor_value, which is inlined into parse_cbor_internal)
|
|
||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
JSON_HEDLEY_NEVER_INLINE
|
|
||||||
bool get_cbor_float()
|
bool get_cbor_float()
|
||||||
{
|
{
|
||||||
NumberType number{};
|
NumberType number{};
|
||||||
@@ -4205,7 +4203,12 @@ class binary_reader
|
|||||||
`char_traits<char_type>::eof()` in that case.
|
`char_traits<char_type>::eof()` in that case.
|
||||||
|
|
||||||
@return character read from the input
|
@return character read from the input
|
||||||
|
|
||||||
|
@note always inlined: GCC otherwise stops inlining the stream adapter's
|
||||||
|
get_character() into parse_cbor_internal once that function grows
|
||||||
|
(+0.45 % instructions for CBOR from a std::istringstream with GCC 13)
|
||||||
*/
|
*/
|
||||||
|
JSON_HEDLEY_ALWAYS_INLINE
|
||||||
char_int_type get()
|
char_int_type get()
|
||||||
{
|
{
|
||||||
++chars_read;
|
++chars_read;
|
||||||
|
|||||||
Generated
+6
-3
@@ -18925,10 +18925,8 @@ class binary_reader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// read a single- or double-precision float (kept out of
|
/// read a single- or double-precision float
|
||||||
/// parse_cbor_value, which is inlined into parse_cbor_internal)
|
|
||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
JSON_HEDLEY_NEVER_INLINE
|
|
||||||
bool get_cbor_float()
|
bool get_cbor_float()
|
||||||
{
|
{
|
||||||
NumberType number{};
|
NumberType number{};
|
||||||
@@ -21982,7 +21980,12 @@ class binary_reader
|
|||||||
`char_traits<char_type>::eof()` in that case.
|
`char_traits<char_type>::eof()` in that case.
|
||||||
|
|
||||||
@return character read from the input
|
@return character read from the input
|
||||||
|
|
||||||
|
@note always inlined: GCC otherwise stops inlining the stream adapter's
|
||||||
|
get_character() into parse_cbor_internal once that function grows
|
||||||
|
(+0.45 % instructions for CBOR from a std::istringstream with GCC 13)
|
||||||
*/
|
*/
|
||||||
|
JSON_HEDLEY_ALWAYS_INLINE
|
||||||
char_int_type get()
|
char_int_type get()
|
||||||
{
|
{
|
||||||
++chars_read;
|
++chars_read;
|
||||||
|
|||||||
Reference in new issue
Block a user