mirror of
https://github.com/fraillt/bitsery.git
synced 2026-06-08 00:03:54 +00:00
Discourage inlining the resize case, as that should happen rather rarely.
If you additionally reuse buffers, this will increase the performance further. The metrics based on some internal benchmarks show a speedup of about 1%: bitsery <dont inline bad cases> BigString: 222092ns ComplexLittleObjects: 34115ns ComplexLittleObjectsBig: 6222801ns bitsery <original> BigString: 242853ns ComplexLittleObjects: 35738ns ComplexLittleObjectsBig: 6334747ns The assembly has been checked to be correct: https://godbolt.org/z/Wr7qvfGrK Additionally, when allocating code, we can tell the compiler that we are not resizing to a lower size, this saves on gcc 14 a few instructions. The improvement should be negligible.
This commit is contained in:
committed by
Mindaugas Vinkelis
parent
cd73aca2f5
commit
be2f295310
@@ -269,12 +269,11 @@ private:
|
||||
|
||||
void maybeResize(size_t newOffset, std::true_type)
|
||||
{
|
||||
if (newOffset > _bufferSize) {
|
||||
traits::BufferAdapterTraits<Buffer>::increaseBufferSize(
|
||||
*_buffer, _currOffset, newOffset);
|
||||
_beginIt = std::begin(*_buffer);
|
||||
_bufferSize = traits::ContainerTraits<Buffer>::size(*_buffer);
|
||||
}
|
||||
if (newOffset > _bufferSize)
|
||||
BITSERY_UNLIKELY
|
||||
{
|
||||
doResize(newOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void maybeResize(BITSERY_MAYBE_UNUSED size_t newOffset, std::false_type)
|
||||
@@ -289,6 +288,14 @@ private:
|
||||
std::copy_n(data, size, _beginIt + static_cast<diff_t>(_currOffset));
|
||||
_currOffset = newOffset;
|
||||
}
|
||||
|
||||
BITSERY_NOINLINE void doResize(size_t newOffset)
|
||||
{
|
||||
traits::BufferAdapterTraits<Buffer>::increaseBufferSize(
|
||||
*_buffer, _currOffset, newOffset);
|
||||
_beginIt = std::begin(*_buffer);
|
||||
_bufferSize = traits::ContainerTraits<Buffer>::size(*_buffer);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -36,12 +36,73 @@
|
||||
BITSERY_BUILD_VERSION_STR( \
|
||||
BITSERY_MAJOR_VERSION, BITSERY_MINOR_VERSION, BITSERY_PATCH_VERSION)
|
||||
|
||||
#if __cplusplus > 201402L
|
||||
#define BITSERY_MAYBE_UNUSED [[maybe_unused]]
|
||||
#define BITSERY_DO_PRAGMA(x) _Pragma(#x)
|
||||
#ifdef __GNUC__
|
||||
#define BITSERY_DISABLE_WARNINGS(...) \
|
||||
BITSERY_DO_PRAGMA(GCC diagnostic push) \
|
||||
BITSERY_DO_PRAGMA(GCC diagnostic ignored __VA_ARGS__)
|
||||
#define BITSERY_ENABLE_WARNINGS() BITSERY_DO_PRAGMA(GCC diagnostic pop)
|
||||
#elif defined(_MSC_VER)
|
||||
#define BITSERY_DISABLE_WARNINGS(...) \
|
||||
BITSERY_DO_PRAGMA(GCC diagnostic push) \
|
||||
BITSERY_DO_PRAGMA(GCC diagnostic ignored __VA_ARGS__) \
|
||||
BITSERY_DO_PRAGMA(GCC diagnostic pop)
|
||||
#define BITSERY_ENABLE_WARNINGS() BITSERY_DO_PRAGMA(GCC diagnostic pop)
|
||||
#else
|
||||
#define BITSERY_DISABLE_WARNINGS(...)
|
||||
#define BITSERY_ENABLE_WARNINGS()
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#define BITSERY_ATTRIBUTE(...) \
|
||||
BITSERY_DISABLE_WARNINGS("-Wfuture-attribute-extensions") \
|
||||
[[__VA_ARGS__]] BITSERY_ENABLE_WARNINGS()
|
||||
#elif defined(__GNUC__)
|
||||
#define BITSERY_ATTRIBUTE(...) [[__VA_ARGS__]]
|
||||
#elif defined(_MSC_VER)
|
||||
#define BITSERY_ATTRIBUTE(...) [[__VA_ARGS__]]
|
||||
#else
|
||||
#define BITSERY_ATTRIBUTE(...) [[__VA_ARGS__]]
|
||||
#endif
|
||||
|
||||
#if __has_cpp_attribute(likely)
|
||||
#define BITSERY_LIKELY BITSERY_ATTRIBUTE(likey)
|
||||
#else
|
||||
#define BITSERY_LIKELY
|
||||
#endif
|
||||
|
||||
#if __has_cpp_attribute(unlikely)
|
||||
#define BITSERY_UNLIKELY BITSERY_ATTRIBUTE(unlikely)
|
||||
#else
|
||||
#define BITSERY_UNLIKELY
|
||||
#endif
|
||||
|
||||
#if __has_cpp_attribute(maybe_unused)
|
||||
#define BITSERY_MAYBE_UNUSED BITSERY_ATTRIBUTE(maybe_unused)
|
||||
#else
|
||||
#define BITSERY_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define BITSERY_NOINLINE __attribute__((noinline))
|
||||
#elif defined(_MSC_VER)
|
||||
#define BITSERY_NOINLINE __declspec(noinline)
|
||||
#else
|
||||
#define BITSERY_NOINLINE
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define BITSERY_ASSUME(cond) \
|
||||
do { \
|
||||
if (!(cond)) \
|
||||
__builtin_unreachable(); \
|
||||
} while (0)
|
||||
#elif defined(_MSC_VER)
|
||||
#define BITSERY_ASSUME(cond) __assume(cond)
|
||||
#else
|
||||
#define BITSERY_ASSUME(cond)
|
||||
#endif
|
||||
|
||||
#include "deserializer.h"
|
||||
#include "serializer.h"
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#ifndef BITSERY_TRAITS_CORE_STD_DEFAULTS_H
|
||||
#define BITSERY_TRAITS_CORE_STD_DEFAULTS_H
|
||||
|
||||
#include "../../bitsery.h"
|
||||
#include "../../details/serialization_common.h"
|
||||
#include "traits.h"
|
||||
|
||||
@@ -103,8 +104,11 @@ struct StdContainerForBufferAdapter<T, true>
|
||||
static_cast<size_t>(static_cast<double>(container.size()) * 1.5) + 128;
|
||||
// make data cache friendly
|
||||
newSize -= newSize % 64; // 64 is cache line size
|
||||
container.resize(
|
||||
(std::max)(newSize > minSize ? newSize : minSize, container.capacity()));
|
||||
auto resize =
|
||||
(std::max)(newSize > minSize ? newSize : minSize, container.capacity());
|
||||
BITSERY_ASSUME(resize >= container.size());
|
||||
BITSERY_ASSUME(resize >= container.capacity());
|
||||
container.resize(resize);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user