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]

Reply via email to