urlyy commented on issue #2885:
URL: https://github.com/apache/fory/issues/2885#issuecomment-3648959438

   @chaokunyang This is the solution I believe requires the least modifications 
to the current code structure to resolve this PR, it is using `generic constant 
parameters` to eliminate branches at compile time and reduce runtime overhead. 
   
   However, this is not very user-friendly for `EXT` users, and if more 
compression modes need to be added in the future, it will also result in very 
long code.
   
   Here is the demo code:
   ```rust
   use std::collections::HashMap;
   
   trait Serializer {
       fn fory_read_data<const COMPRESS_INT: bool, const COMPRESS_LONG_MODE: 
u8>() -> Self;
   }
   
   impl Serializer for i32 {
       fn fory_read_data<const COMPRESS_INT: bool, const COMPRESS_LONG_MODE: 
u8>() -> Self {
           match COMPRESS_INT {
               true => {
                   println!("read_varint32");
                   return 21
               }
               false => {
                   println!("read_i32");
                   return 42;
               }
           }
       }
   }
   
   // for container, should pass the const generic parameters to the element.
   impl<K: Serializer + Eq + std::hash::Hash, V: Serializer> Serializer for 
HashMap<K, V> {
       fn fory_read_data<const COMPRESS_INT: bool, const COMPRESS_LONG_MODE: 
u8>() -> Self {
           K::fory_read_data::<COMPRESS_INT, COMPRESS_LONG_MODE>();
           V::fory_read_data::<COMPRESS_INT, COMPRESS_LONG_MODE>();
           unimplemented!()
       }
   }
   
   // same as i64
   // And for more compression, we should add more const generic parameters.
   
   
   // but for EXT type, user should write all const generic parameters when 
implement.
   struct CustomType;
   impl Serializer for CustomType {
       fn fory_read_data<const COMPRESS_INT: bool, const COMPRESS_LONG_MODE: 
u8>() -> Self {
           unimplemented!()
       }
   }
   
   #[repr(u8)]
   enum CompressLongMode {
       None,
       Var,
       Sli,
   }
   
   fn main() {
       // Based on #[fory(compress_int = true)] and #[fory(compress_long = 
xx)], pass different generic constant parameters at compile time.
       let a = i32::fory_read_data::<true, {CompressLongMode::None as u8}>();
       println!("Result: {}", a);
       let b = i32::fory_read_data::<false, {CompressLongMode::Sli as u8}>();
       println!("Result: {}", b);
   }
   ```
   I've also considered custom types like `I32Uncompressed`, but it cannot 
return an `i32` during reading. 
   Or if we add an extra `type_id` parameter to `read_data`/`write_data` and 
introduce branches for various compression modes of `i32` and `i64`, it would 
increase runtime overhead. 
   
   Do you have any suggestions?


-- 
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