chaokunyang opened a new issue, #2721:
URL: https://github.com/apache/fory/issues/2721

   ### Feature Request
   
   unroll rust struct serialization loop for better peprformance to reduce 
field name compare, and loop unroll can speed up code cache and give better 
branch predict too.
   
   ### Is your feature request related to a problem? Please describe
   
   _No response_
   
   ### Describe the solution you'd like
   
   Currently `ForyObject` macro generate code like:
   
   ```rust
   impl fory_core::serializer::Serializer for Node {
       fn fory_get_type_id(fory: &fory_core::fory::Fory) -> u32 {
           
fory.get_type_resolver().get_type_id(&std::any::TypeId::of::<Self>(), 0u32)
       }
       fn fory_type_id_dyn(&self, fory: &fory_core::fory::Fory) -> u32 {
           Self::fory_get_type_id(fory)
       }
       fn as_any(&self) -> &dyn std::any::Any {
           self
       }
       fn fory_reserved_space() -> usize {
           <Vec<
               Rc<RefCell<Node>>,
           > as fory_core::serializer::Serializer>::fory_reserved_space()
               + fory_core::types::SIZE_OF_REF_AND_TYPE
               + <RcWeak<
                   RefCell<Node>,
               > as fory_core::serializer::Serializer>::fory_reserved_space()
               + fory_core::types::SIZE_OF_REF_AND_TYPE
               + <i32 as 
fory_core::serializer::Serializer>::fory_reserved_space()
               + fory_core::types::SIZE_OF_REF_AND_TYPE
       }
       fn fory_write_type_info(
           context: &mut fory_core::resolver::context::WriteContext,
           is_field: bool,
       ) {
           fory_core::serializer::struct_::write_type_info::<Self>(context, 
is_field)
       }
       fn fory_read_type_info(
           context: &mut fory_core::resolver::context::ReadContext,
           is_field: bool,
       ) {
           fory_core::serializer::struct_::read_type_info::<Self>(context, 
is_field)
       }
       fn fory_write_data(
           &self,
           context: &mut fory_core::resolver::context::WriteContext,
           is_field: bool,
       ) {
           let sorted_field_names = <Self as 
fory_core::serializer::StructSerializer>::fory_get_sorted_field_names(
               context.get_fory(),
           );
           for field_name in sorted_field_names {
               match field_name.as_str() {
                   "children" => {
                       fory_core::serializer::Serializer::fory_write(
                           &self.children,
                           context,
                           true,
                       );
                   }
                   "parent" => {
                       fory_core::serializer::Serializer::fory_write(
                           &self.parent,
                           context,
                           true,
                       );
                   }
                   "value" => {
                       let skip_ref_flag = 
fory_core::serializer::get_skip_ref_flag::<
                           i32,
                       >(context.get_fory());
                       fory_core::serializer::write_ref_info_data::<
                           i32,
                       >(&self.value, context, true, skip_ref_flag, false);
                   }
                   _ => ::core::panicking::panic("internal error: entered 
unreachable code"),
               }
           }
       }
       fn fory_read_data(
           context: &mut fory_core::resolver::context::ReadContext,
           is_field: bool,
       ) -> Result<Self, fory_core::error::Error> {
           let mut _children: Option<Vec<Rc<RefCell<Node>>>> = None;
           let mut _parent: Option<RcWeak<RefCell<Node>>> = None;
           let mut _value: Option<i32> = None;
           let sorted_field_names = <Self as 
fory_core::serializer::StructSerializer>::fory_get_sorted_field_names(
               context.get_fory(),
           );
           for field_name in sorted_field_names {
               match field_name.as_str() {
                   "children" => {
                       _children = Some(
                           
fory_core::serializer::Serializer::fory_read(context, true)?,
                       );
                   }
                   "parent" => {
                       _parent = Some(
                           
fory_core::serializer::Serializer::fory_read(context, true)?,
                       );
                   }
                   "value" => {
                       let skip_ref_flag = 
fory_core::serializer::get_skip_ref_flag::<
                           i32,
                       >(context.get_fory());
                       _value = Some(
                           fory_core::serializer::read_ref_info_data::<
                               i32,
                           >(context, true, skip_ref_flag, false)?,
                       );
                   }
                   _ => ::core::panicking::panic("internal error: entered 
unreachable code"),
               }
           }
           Ok(Self {
               children: _children.unwrap_or_default(),
               parent: _parent.unwrap_or_default(),
               value: _value.unwrap_or_default(),
           })
       }
       fn fory_write(
           &self,
           context: &mut fory_core::resolver::context::WriteContext,
           is_field: bool,
       ) {
           fory_core::serializer::struct_::write::<Self>(self, context, 
is_field)
       }
       fn fory_read(
           context: &mut fory_core::resolver::context::ReadContext,
           is_field: bool,
       ) -> Result<Self, fory_core::error::Error> {
           let ref_flag = context.reader.read_i8();
           if ref_flag == (fory_core::types::RefFlag::NotNullValue as i8)
               || ref_flag == (fory_core::types::RefFlag::RefValue as i8)
           {
               match context.get_fory().get_mode() {
                   fory_core::types::Mode::SchemaConsistent => {
                       <Self as 
fory_core::serializer::Serializer>::fory_read_type_info(
                           context,
                           false,
                       );
                       <Self as 
fory_core::serializer::Serializer>::fory_read_data(
                           context,
                           false,
                       )
                   }
                   fory_core::types::Mode::Compatible => {
                       <Node as 
fory_core::serializer::StructSerializer>::fory_read_compatible(
                           context,
                       )
                   }
                   _ => ::core::panicking::panic("internal error: entered 
unreachable code"),
               }
           } else if ref_flag == (fory_core::types::RefFlag::Null as i8) {
               Ok(<Self as fory_core::serializer::ForyDefault>::fory_default())
           } else if ref_flag == (fory_core::types::RefFlag::Ref as i8) {
               Err(fory_core::error::Error::Ref)
           } else {
               Err(
                   fory_core::error::AnyhowError::msg("Unknown ref flag, 
value:{ref_flag}"),
               )?
           }
       }
   }
   ```
   
   This is not efficient, especially the loop `for field_name in 
sorted_field_names` compare field name every time. 
   
   ### Describe alternatives you've considered
   
   We should just generate code for every field instead of using loop
   
   ### Additional context
   
   _No response_


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to