@@ -433,11 +433,64 @@ impl ByteMessageBuilder {
433433 }
434434
435435 /// Clear the builder and start fresh
436+ ///
437+ /// This method completely replaces the builder with a new instance,
438+ /// releasing any allocated memory. Use this when memory usage is a concern
439+ /// or when you want absolute certainty of a fresh state.
440+ ///
441+ /// For performance-critical code or when creating many messages in sequence,
442+ /// consider using `reset()` instead, which preserves memory allocation.
443+ ///
444+ /// After clearing, you'll need to configure the builder for the desired message type
445+ /// by calling `for_quantum_operations()` or `for_measurement_results()`.
436446 pub fn clear ( & mut self ) -> & mut Self {
437447 * self = Self :: new ( ) ;
438448 self
439449 }
440450
451+ /// Reset the builder state while preserving allocated memory
452+ ///
453+ /// Unlike `clear()`, this method preserves the allocated memory buffer
454+ /// for better performance when reusing the same builder multiple times.
455+ /// This is the recommended method for performance-critical code,
456+ /// especially when creating many messages in sequence.
457+ ///
458+ /// After resetting, you'll need to configure the builder for the desired message type
459+ /// by calling `for_quantum_operations()` or `for_measurement_results()`:
460+ ///
461+ /// ```
462+ /// # use pecos_engines::channels::byte::builder::ByteMessageBuilder;
463+ /// let mut builder = ByteMessageBuilder::new();
464+ ///
465+ /// // Create first message
466+ /// let _ = builder.for_quantum_operations();
467+ /// builder.add_h(&[0]);
468+ /// let message1 = builder.build();
469+ ///
470+ /// // Reset and configure for next message
471+ /// builder.reset();
472+ /// let _ = builder.for_quantum_operations();
473+ /// builder.add_h(&[1]);
474+ /// let message2 = builder.build();
475+ /// ```
476+ ///
477+ /// If memory usage is a concern or you want to ensure a completely fresh state,
478+ /// consider using `clear()` instead.
479+ pub fn reset ( & mut self ) -> & mut Self {
480+ // Truncate the buffer to just the batch header size
481+ self . buffer . truncate ( size_of :: < BatchHeader > ( ) ) ;
482+
483+ // Zero out the batch header area more efficiently
484+ // Using slice fill is more efficient than a loop for small fixed-size areas
485+ self . buffer . fill ( 0 ) ;
486+
487+ // Reset message count and mode
488+ self . msg_count = 0 ;
489+ self . mode = BuilderMode :: Empty ;
490+
491+ self
492+ }
493+
441494 /// Build the final message batch without type checking
442495 pub fn build_unchecked ( & mut self ) -> ByteMessage {
443496 // Calculate total size and update batch header
@@ -703,4 +756,124 @@ mod tests {
703756 // Check the message count again
704757 assert_eq ! ( builder. message_count( ) , 1 ) ;
705758 }
759+
760+ #[ test]
761+ fn test_reset ( ) {
762+ // Create a builder
763+ let mut builder = ByteMessageBuilder :: new ( ) ;
764+ let _ = builder. for_quantum_operations ( ) ;
765+
766+ // Add some gates
767+ builder. add_h ( & [ 0 ] ) ;
768+ builder. add_cx ( & [ 0 ] , & [ 1 ] ) ;
769+
770+ // Check the message count
771+ assert_eq ! ( builder. message_count( ) , 3 ) ;
772+
773+ // Get the buffer capacity before reset
774+ let capacity_before = builder. buffer . capacity ( ) ;
775+
776+ // Reset the builder
777+ builder. reset ( ) ;
778+
779+ // Check the message count after reset
780+ assert_eq ! ( builder. message_count( ) , 0 ) ;
781+ assert_eq ! ( builder. mode( ) , BuilderMode :: Empty ) ;
782+
783+ // Verify the buffer capacity is preserved
784+ assert_eq ! ( builder. buffer. capacity( ) , capacity_before) ;
785+
786+ // Configure for quantum operations again
787+ let _ = builder. for_quantum_operations ( ) ;
788+
789+ // Add a new gate
790+ builder. add_h ( & [ 0 ] ) ;
791+
792+ // Check the message count again
793+ assert_eq ! ( builder. message_count( ) , 2 ) ;
794+
795+ // Build the message and verify it's valid
796+ let message = builder. build ( ) ;
797+ let commands = message. parse_quantum_operations ( ) . unwrap ( ) ;
798+ assert_eq ! ( commands. len( ) , 1 ) ;
799+ assert_eq ! ( commands[ 0 ] . gate_type, GateTypeId :: H ) ;
800+ }
801+
802+ #[ test]
803+ fn compare_clear_vs_reset_performance ( ) {
804+ const ITERATIONS : usize = 5000 ;
805+ const TRIALS : usize = 5 ;
806+
807+ let mut clear_durations = Vec :: with_capacity ( TRIALS ) ;
808+ let mut reset_durations = Vec :: with_capacity ( TRIALS ) ;
809+
810+ for _ in 0 ..TRIALS {
811+ // Test with clear()
812+ let start_clear = std:: time:: Instant :: now ( ) ;
813+ {
814+ let mut builder = ByteMessageBuilder :: new ( ) ;
815+
816+ for i in 0 ..ITERATIONS {
817+ if i > 0 {
818+ builder. clear ( ) ;
819+ }
820+
821+ // Configure for quantum operations
822+ let _ = builder. for_quantum_operations ( ) ;
823+
824+ // Add a gate
825+ builder. add_h ( & [ 0 ] ) ;
826+
827+ // Build the message
828+ let _message = builder. build ( ) ;
829+ }
830+ }
831+ clear_durations. push ( start_clear. elapsed ( ) ) ;
832+
833+ // Test with reset()
834+ let start_reset = std:: time:: Instant :: now ( ) ;
835+ {
836+ let mut builder = ByteMessageBuilder :: new ( ) ;
837+
838+ for i in 0 ..ITERATIONS {
839+ if i > 0 {
840+ builder. reset ( ) ;
841+ }
842+
843+ // Configure for quantum operations
844+ let _ = builder. for_quantum_operations ( ) ;
845+
846+ // Add a gate
847+ builder. add_h ( & [ 0 ] ) ;
848+
849+ // Build the message
850+ let _message = builder. build ( ) ;
851+ }
852+ }
853+ reset_durations. push ( start_reset. elapsed ( ) ) ;
854+ }
855+
856+ // Calculate averages
857+ #[ allow( clippy:: cast_precision_loss) ]
858+ let avg_clear = clear_durations
859+ . iter ( )
860+ . map ( std:: time:: Duration :: as_secs_f64)
861+ . sum :: < f64 > ( )
862+ / ( TRIALS as f64 ) ;
863+ #[ allow( clippy:: cast_precision_loss) ]
864+ let avg_reset = reset_durations
865+ . iter ( )
866+ . map ( std:: time:: Duration :: as_secs_f64)
867+ . sum :: < f64 > ( )
868+ / ( TRIALS as f64 ) ;
869+
870+ // Print results
871+ println ! ( "Performance comparison ({TRIALS} trials of {ITERATIONS} iterations each):" ) ;
872+ println ! ( " clear() + for_quantum_operations(): {avg_clear:.6}s (average)" ) ;
873+ println ! ( " reset() + for_quantum_operations(): {avg_reset:.6}s (average)" ) ;
874+ println ! ( " reset() approach is {:.2}x faster" , avg_clear / avg_reset) ;
875+
876+ // We don't assert anything here as performance can vary by environment,
877+ // but reset() should generally be faster
878+ }
706879}
0 commit comments