From 5e7cc3d7434a8f1b945cc4b716d2597d44843e6e Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Wed, 12 Aug 2026 20:14:11 +0800 Subject: [PATCH] perf(cpp): simplify TypeMeta index tracking --- cpp/fory/serialization/context.cc | 38 ++++++++++--------------------- cpp/fory/serialization/context.h | 4 +--- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/cpp/fory/serialization/context.cc b/cpp/fory/serialization/context.cc index b6ed7098ab..023a9771b8 100644 --- a/cpp/fory/serialization/context.cc +++ b/cpp/fory/serialization/context.cc @@ -77,31 +77,19 @@ WriteContext::write_type_meta(const std::type_index &type_id) { } void WriteContext::write_type_meta(const TypeInfo *type_info) { - const uint64_t key = - static_cast(reinterpret_cast(type_info)); - if (!type_info_index_map_active_) { - if (!has_first_type_info_) { - has_first_type_info_ = true; - first_type_info_ = type_info; - buffer_.write_uint8(0); // (index << 1), index=0 - buffer_.write_bytes(type_info->type_def.data(), - type_info->type_def.size()); - return; - } - if (type_info == first_type_info_) { - buffer_.write_uint8(1); // (index << 1) | 1, index=0 - return; - } - type_info_index_map_active_ = true; - write_type_info_index_map_.clear(); - const uint64_t first_key = - static_cast(reinterpret_cast(first_type_info_)); - write_type_info_index_map_.put(first_key, 0); - } else if (type_info == first_type_info_) { + if (first_type_info_ == nullptr) { + first_type_info_ = type_info; + buffer_.write_uint8(0); // (index << 1), index=0 + buffer_.write_bytes(type_info->type_def.data(), type_info->type_def.size()); + return; + } + if (type_info == first_type_info_) { buffer_.write_uint8(1); // (index << 1) | 1, index=0 return; } + const uint64_t key = + static_cast(reinterpret_cast(type_info)); if (auto *entry = write_type_info_index_map_.find(key)) { // Reference to previously written type: (index << 1) | 1, LSB=1 uint32_t marker = static_cast((entry->value << 1) | 1); @@ -114,7 +102,7 @@ void WriteContext::write_type_meta(const TypeInfo *type_info) { } // New type: index << 1, LSB=0, followed by TypeDef bytes inline - uint32_t index = static_cast(write_type_info_index_map_.size()); + uint32_t index = static_cast(write_type_info_index_map_.size() + 1); uint32_t marker = static_cast(index << 1); if (marker < 0x80) { buffer_.write_uint8(static_cast(marker)); @@ -404,13 +392,11 @@ void WriteContext::reset() { if (config_->track_ref) { ref_writer_.reset(); } - // Clear meta map for streaming TypeMeta (size is used as counter) - if (type_info_index_map_active_) { + // Clear meta map for streaming TypeMeta. + if (!write_type_info_index_map_.empty()) { write_type_info_index_map_.clear(); } first_type_info_ = nullptr; - has_first_type_info_ = false; - type_info_index_map_active_ = false; current_dyn_depth_ = 0; buffer_.clear_output_stream(); output_stream_ = nullptr; diff --git a/cpp/fory/serialization/context.h b/cpp/fory/serialization/context.h index cdd503033f..9cdc417ed9 100644 --- a/cpp/fory/serialization/context.h +++ b/cpp/fory/serialization/context.h @@ -356,12 +356,10 @@ class WriteContext { OutputStream *output_stream_ = nullptr; // Meta sharing state (for streaming inline TypeMeta) - // Maps TypeInfo* to index for reference tracking - uses map size as counter + // The first TypeInfo has index 0; the map stores later types at size + 1. util::FlatIntMap write_type_info_index_map_; // Fast path for the common single-type stream: avoid hash map lookups. const TypeInfo *first_type_info_ = nullptr; - bool has_first_type_info_ = false; - bool type_info_index_map_active_ = false; }; /// Read context for deserialization operations.