Skip to content

Conversation

@chaokunyang
Copy link
Collaborator

@chaokunyang chaokunyang commented Nov 30, 2025

Why?

Eliminate shared_ptr<TypeInfo> overhead from the hot serialization code path. The atomic reference counting in shared_ptr adds unnecessary overhead when TypeInfo objects are accessed frequently during serialization/deserialization. By switching to raw pointers with clear ownership semantics, we can improve performance on the critical path.

What does this PR do?

This PR refactors the C++ serialization library's TypeInfo ownership model:

TypeInfo Changes

  • Changed internal fields (type_meta, encoded_namespace, encoded_type_name) from shared_ptr to unique_ptr
  • Added TypeInfo::deep_clone() method for creating deep copies
  • Made TypeInfo non-copyable (deleted copy constructor/assignment)

TypeResolver Storage Changes

  • Changed from map<K, shared_ptr<TypeInfo>> to primary storage pattern:
    • Primary storage: vector<unique_ptr<TypeInfo>> (owns all TypeInfo objects)
    • Lookup maps: Raw pointers (TypeInfo*) pointing to primary storage
  • Lookup methods now return:
    • const TypeInfo* for nullable lookups (get_type_info_by_id, get_type_info_by_name)
    • Result<const TypeInfo&> for error-handling lookups (get_type_info, get_struct_type_info<T>)

Context Ownership Changes

  • WriteContext and ReadContext now hold unique_ptr<TypeResolver> instead of shared_ptr
  • Contexts are created lazily after type resolver finalization with deep-cloned resolvers
  • Fory class uses std::optional for contexts to support lazy initialization

Code Pattern Updates

  • Updated all call sites that used FORY_TRY with Result<const TypeInfo&> to use explicit error handling (since TypeInfo is now non-copyable)
  • Updated read_struct_fields_compatible signature from shared_ptr<TypeMeta> to const TypeMeta*

Related issues

#2906
#2944
#2958

Does this PR introduce any user-facing change?

  • Does this PR introduce any public API change?
    • Internal API only. TypeResolver lookup methods now return raw pointers or references instead of shared_ptr. User-facing Fory API remains unchanged.
  • Does this PR introduce any binary protocol compatibility change?

Benchmark

This change eliminates atomic reference counting overhead on the hot serialization path:

  • shared_ptr copy/destruction involves atomic increment/decrement operations
  • Raw pointer access is a simple dereference with no atomic operations
  • Deep cloning happens once during context creation, not per-serialization

Expected improvement: Reduced CPU overhead in tight serialization loops, especially noticeable when serializing many small objects where TypeInfo lookups are frequent relative to data size.

@chaokunyang chaokunyang changed the title feat(c++): remove shared_ptr from type info perf(c++): remove shared_ptr from type info to reduce atomic counter cost Nov 30, 2025
@chaokunyang chaokunyang merged commit c11d589 into apache:main Nov 30, 2025
57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants