This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git
The following commit(s) were added to refs/heads/main by this push:
new 3b1658a1e perf(c++): improve the serialization performance of
array/collection (#2986)
3b1658a1e is described below
commit 3b1658a1e8c600e900b3bf4eabc39858d7c72e84
Author: LiangliangSui <[email protected]>
AuthorDate: Thu Dec 4 17:45:37 2025 +0800
perf(c++): improve the serialization performance of array/collection (#2986)
## Why?
## What does this PR do?
improve the serialization performance of array/collection
## Related issues
https://github.com/apache/fory/issues/2978
---------
Signed-off-by: Liangliang Sui <[email protected]>
---
cpp/fory/serialization/array_serializer.h | 21 +++++++++++++++++----
cpp/fory/serialization/collection_serializer.h | 26 +++++++++++++++++++++-----
2 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/cpp/fory/serialization/array_serializer.h
b/cpp/fory/serialization/array_serializer.h
index c21c5f78f..d5f66d2a6 100644
--- a/cpp/fory/serialization/array_serializer.h
+++ b/cpp/fory/serialization/array_serializer.h
@@ -71,13 +71,19 @@ struct Serializer<
static Result<void, Error> write_data(const std::array<T, N> &arr,
WriteContext &ctx) {
+ Buffer &buffer = ctx.buffer();
+ // bulk write may write 8 bytes for varint32
+ constexpr size_t max_size = 8 + N * sizeof(T);
+ buffer.Grow(static_cast<uint32_t>(max_size));
+ uint32_t writer_index = buffer.writer_index();
// Write array length
- ctx.write_varuint32(static_cast<uint32_t>(N));
+ writer_index += buffer.PutVarUint32(writer_index,
static_cast<uint32_t>(N));
// Write raw binary data
if constexpr (N > 0) {
- ctx.write_bytes(arr.data(), N * sizeof(T));
+ buffer.UnsafePut(writer_index, arr.data(), N * sizeof(T));
}
+ buffer.WriterIndex(writer_index + N * sizeof(T));
return Result<void, Error>();
}
@@ -149,14 +155,21 @@ template <size_t N> struct Serializer<std::array<bool,
N>> {
static Result<void, Error> write_data(const std::array<bool, N> &arr,
WriteContext &ctx) {
+ Buffer &buffer = ctx.buffer();
+ // bulk write may write 8 bytes for varint32
+ constexpr size_t max_size = 8 + N;
+ buffer.Grow(static_cast<uint32_t>(max_size));
+ uint32_t writer_index = buffer.writer_index();
// Write array length
- ctx.write_varuint32(static_cast<uint32_t>(N));
+ writer_index += buffer.PutVarUint32(writer_index,
static_cast<uint32_t>(N));
// Write each boolean as a byte (per spec, bool is serialized as int16,
// but for arrays we use packed bytes for efficiency)
for (size_t i = 0; i < N; ++i) {
- ctx.write_uint8(arr[i] ? 1 : 0);
+ buffer.UnsafePutByte(writer_index + i,
+ static_cast<uint8_t>(arr[i] ? 1 : 0));
}
+ buffer.WriterIndex(writer_index + N);
return Result<void, Error>();
}
diff --git a/cpp/fory/serialization/collection_serializer.h
b/cpp/fory/serialization/collection_serializer.h
index dfb335748..a307e5d5d 100644
--- a/cpp/fory/serialization/collection_serializer.h
+++ b/cpp/fory/serialization/collection_serializer.h
@@ -561,10 +561,18 @@ struct Serializer<
return Unexpected(
Error::invalid("Vector byte size exceeds uint32_t range"));
}
- ctx.write_varuint32(static_cast<uint32_t>(total_bytes));
+ Buffer &buffer = ctx.buffer();
+ // bulk write may write 8 bytes for varint32
+ size_t max_size = 8 + total_bytes;
+ buffer.Grow(static_cast<uint32_t>(max_size));
+ uint32_t writer_index = buffer.writer_index();
+ writer_index +=
+ buffer.PutVarUint32(writer_index, static_cast<uint32_t>(total_bytes));
if (total_bytes > 0) {
- ctx.write_bytes(vec.data(), static_cast<uint32_t>(total_bytes));
+ buffer.UnsafePut(writer_index, vec.data(),
+ static_cast<uint32_t>(total_bytes));
}
+ buffer.WriterIndex(writer_index + static_cast<uint32_t>(total_bytes));
return Result<void, Error>();
}
@@ -852,10 +860,18 @@ template <typename Alloc> struct
Serializer<std::vector<bool, Alloc>> {
static inline Result<void, Error>
write_data(const std::vector<bool, Alloc> &vec, WriteContext &ctx) {
- ctx.write_varuint32(static_cast<uint32_t>(vec.size()));
- for (bool value : vec) {
- ctx.write_uint8(value ? 1 : 0);
+ Buffer &buffer = ctx.buffer();
+ // bulk write may write 8 bytes for varint32
+ size_t max_size = 8 + vec.size();
+ buffer.Grow(static_cast<uint32_t>(max_size));
+ uint32_t writer_index = buffer.writer_index();
+ writer_index +=
+ buffer.PutVarUint32(writer_index, static_cast<uint32_t>(vec.size()));
+ for (size_t i = 0; i < vec.size(); ++i) {
+ buffer.UnsafePutByte(writer_index + i,
+ static_cast<uint8_t>(vec[i] ? 1 : 0));
}
+ buffer.WriterIndex(writer_index + vec.size());
return Result<void, Error>();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]