1717// This makes for some ugly code, but it is faster. Hopefully in the future
1818// with MIR support the compiler will get smarter about this.
1919
20- use std:: { str, slice, char, f64 } ;
20+ use std:: { ptr , mem , str, slice, char, f64 } ;
2121use object:: Object ;
2222use { JsonValue , Error , Result } ;
2323
@@ -53,18 +53,6 @@ struct Parser<'a> {
5353
5454 // Lenght of the source
5555 length : usize ,
56-
57- // Current depth. Objects and arrays increment depth when they
58- // start being parsed, decrement when they stop being parsed.
59- depth : usize ,
60-
61- // Size stack is an auxiliary array holding expected heap allocation
62- // sizes on each level of depth, up to 16. When an array of objects,
63- // the size stack will be set to the length of the first object parsed,
64- // so that each consecutive object can do a guess for a precise heap
65- // allocation for it's entires, reducing the amount of reallocations
66- // for large files conisderably!
67- size_stack : [ usize ; 16 ] ,
6856}
6957
7058
@@ -423,8 +411,6 @@ impl<'a> Parser<'a> {
423411 byte_ptr : source. as_ptr ( ) ,
424412 index : 0 ,
425413 length : source. len ( ) ,
426- depth : 0 ,
427- size_stack : [ 3 ; 16 ] ,
428414 }
429415 }
430416
@@ -721,22 +707,6 @@ impl<'a> Parser<'a> {
721707 Ok ( num * exponent_to_power ( e * sign) )
722708 }
723709
724- #[ inline( always) ]
725- fn set_alloc_size ( & mut self , size : usize ) {
726- if self . depth < 16 {
727- self . size_stack [ self . depth ] = size;
728- }
729- }
730-
731- #[ inline( always) ]
732- fn get_alloc_size ( & mut self ) -> usize {
733- if self . depth < 16 {
734- self . size_stack [ self . depth ]
735- } else {
736- 3
737- }
738- }
739-
740710 // Given how compilcated reading numbers and strings is, reading objects
741711 // is actually pretty simple.
742712 fn read_object ( & mut self ) -> Result < Object > {
@@ -745,9 +715,7 @@ impl<'a> Parser<'a> {
745715 b'\"' => expect_string!( self )
746716 } ;
747717
748- let mut object = Object :: with_capacity ( self . get_alloc_size ( ) ) ;
749-
750- self . depth += 1 ;
718+ let mut object = Object :: with_capacity ( 3 ) ;
751719
752720 expect ! ( self , b':' ) ;
753721
@@ -767,36 +735,51 @@ impl<'a> Parser<'a> {
767735 object. insert ( key, expect_value ! ( self ) ) ;
768736 }
769737
770- self . depth -= 1 ;
771-
772- self . set_alloc_size ( object. len ( ) ) ;
773-
774738 Ok ( object)
775739 }
776740
777741 // And reading arrays is simpler still!
778742 fn read_array ( & mut self ) -> Result < Vec < JsonValue > > {
779743 let first = expect_value ! { self , b']' => return Ok ( Vec :: new( ) ) } ;
780744
781- let mut array = Vec :: with_capacity ( self . get_alloc_size ( ) ) ;
745+ let mut array = Vec :: with_capacity ( 2 ) ;
782746
783- self . depth += 1 ;
747+ unsafe {
748+ // First member can be written to the array without any checks!
749+ ptr:: copy_nonoverlapping (
750+ & first as * const JsonValue ,
751+ array. as_mut_ptr ( ) ,
752+ 1
753+ ) ;
754+ mem:: forget ( first) ;
755+ array. set_len ( 1 ) ;
756+ }
784757
785- array. push ( first) ;
758+ expect ! {
759+ self ,
760+ b']' => return Ok ( array) ,
761+ b',' => {
762+ // Same for the second one!
763+ let value = expect_value!( self ) ;
764+ unsafe {
765+ ptr:: copy_nonoverlapping(
766+ & value as * const JsonValue ,
767+ array. as_mut_ptr( ) . offset( 1 ) ,
768+ 1
769+ ) ;
770+ mem:: forget( value) ;
771+ array. set_len( 2 ) ;
772+ }
773+ }
774+ }
786775
787776 loop {
788777 expect ! { self ,
789778 b']' => break ,
790- b',' => {
791- array. push( expect_value!( self ) ) ;
792- }
779+ b',' => array. push( expect_value!( self ) )
793780 } ;
794781 }
795782
796- self . depth -= 1 ;
797-
798- self . set_alloc_size ( array. len ( ) ) ;
799-
800783 Ok ( array)
801784 }
802785
0 commit comments