1
+ use std:: borrow:: Cow ;
2
+
1
3
use aws_smithy_cbor:: decode:: Decoder ;
2
4
use criterion:: { black_box, criterion_group, criterion_main, Criterion } ;
3
5
@@ -13,37 +15,75 @@ pub fn str_benchmark(c: &mut Criterion) {
13
15
0xff ,
14
16
] ;
15
17
16
- c. bench_function ( "definite str_alt " , |b| {
18
+ c. bench_function ( "definite str() " , |b| {
17
19
b. iter ( || {
18
20
let mut decoder = Decoder :: new ( & definite_bytes) ;
19
- let x = black_box ( decoder. str_alt ( ) ) ;
21
+ let x = black_box ( decoder. str ( ) ) ;
20
22
assert ! ( matches!( x. unwrap( ) . as_ref( ) , "thisIsAKey" ) ) ;
21
23
} )
22
24
} ) ;
23
- c. bench_function ( "indefinite str_alt" , |b| {
25
+
26
+ c. bench_function ( "definite str_alt" , |b| {
24
27
b. iter ( || {
25
- let mut decoder = Decoder :: new ( & indefinite_bytes) ;
26
- let x = black_box ( decoder . str_alt ( ) ) ;
28
+ let mut decoder = minicbor :: decode :: Decoder :: new ( & indefinite_bytes) ;
29
+ let x = black_box ( str_alt ( & mut decoder ) ) ;
27
30
assert ! ( matches!( x. unwrap( ) . as_ref( ) , "thisIsAKey" ) ) ;
28
31
} )
29
32
} ) ;
30
33
31
- c. bench_function ( "definite str()" , |b| {
34
+ c. bench_function ( "indefinite str()" , |b| {
32
35
b. iter ( || {
33
- let mut decoder = Decoder :: new ( & definite_bytes ) ;
36
+ let mut decoder = Decoder :: new ( & indefinite_bytes ) ;
34
37
let x = black_box ( decoder. str ( ) ) ;
35
38
assert ! ( matches!( x. unwrap( ) . as_ref( ) , "thisIsAKey" ) ) ;
36
39
} )
37
40
} ) ;
38
- c. bench_function ( "indefinite str()" , |b| {
41
+
42
+ c. bench_function ( "indefinite str_alt" , |b| {
39
43
b. iter ( || {
40
- let mut decoder = Decoder :: new ( & indefinite_bytes) ;
41
- let x = black_box ( decoder . str ( ) ) ;
44
+ let mut decoder = minicbor :: decode :: Decoder :: new ( & indefinite_bytes) ;
45
+ let x = black_box ( str_alt ( & mut decoder ) ) ;
42
46
assert ! ( matches!( x. unwrap( ) . as_ref( ) , "thisIsAKey" ) ) ;
43
47
} )
44
48
} ) ;
45
49
}
46
50
51
+ // The following seems to be a bit slower than the implementation that we have
52
+ // kept in the `aws_smithy_cbor::Decoder`.
53
+ pub fn string_alt < ' b > (
54
+ decoder : & ' b mut minicbor:: Decoder < ' b > ,
55
+ ) -> Result < String , minicbor:: decode:: Error > {
56
+ decoder. str_iter ( ) ?. collect ( )
57
+ }
58
+
59
+ // The following seems to be a bit slower than the implementation that we have
60
+ // kept in the `aws_smithy_cbor::Decoder`.
61
+ fn str_alt < ' b > (
62
+ decoder : & ' b mut minicbor:: Decoder < ' b > ,
63
+ ) -> Result < Cow < ' b , str > , minicbor:: decode:: Error > {
64
+ // This implementation uses `next` twice to see if there is
65
+ // another str chunk. If there is, it returns a owned `String`.
66
+ let mut chunks_iter = decoder. str_iter ( ) ?;
67
+ let head = match chunks_iter. next ( ) {
68
+ Some ( Ok ( head) ) => head,
69
+ None => return Ok ( Cow :: Borrowed ( "" ) ) ,
70
+ Some ( Err ( e) ) => return Err ( e) ,
71
+ } ;
72
+
73
+ match chunks_iter. next ( ) {
74
+ None => Ok ( Cow :: Borrowed ( head) ) ,
75
+ Some ( Err ( e) ) => Err ( e) ,
76
+ Some ( Ok ( next) ) => {
77
+ let mut concatenated_string = String :: from ( head) ;
78
+ concatenated_string. push_str ( next) ;
79
+ for chunk in chunks_iter {
80
+ concatenated_string. push_str ( chunk?) ;
81
+ }
82
+ Ok ( Cow :: Owned ( concatenated_string) )
83
+ }
84
+ }
85
+ }
86
+
47
87
// We have two `string` implementations. One uses `collect` the other
48
88
// uses `String::new` followed by `string::push`.
49
89
pub fn string_benchmark ( c : & mut Criterion ) {
@@ -61,53 +101,31 @@ pub fn string_benchmark(c: &mut Criterion) {
61
101
c. bench_function ( "definite string()" , |b| {
62
102
b. iter ( || {
63
103
let mut decoder = Decoder :: new ( & definite_bytes) ;
64
- let _ = black_box ( decoder. str ( ) ) ;
65
- } )
66
- } ) ;
67
-
68
- c. bench_function ( "indefinite string()" , |b| {
69
- b. iter ( || {
70
- let mut decoder = Decoder :: new ( & indefinite_bytes) ;
71
- let _ = black_box ( decoder. str ( ) ) ;
104
+ let _ = black_box ( decoder. string ( ) ) ;
72
105
} )
73
106
} ) ;
74
107
75
108
c. bench_function ( "definite string_alt()" , |b| {
76
109
b. iter ( || {
77
- let mut decoder = Decoder :: new ( & definite_bytes ) ;
78
- let _ = black_box ( decoder . str_alt ( ) ) ;
110
+ let mut decoder = minicbor :: decode :: Decoder :: new ( & indefinite_bytes ) ;
111
+ let _ = black_box ( string_alt ( & mut decoder ) ) ;
79
112
} )
80
113
} ) ;
81
114
82
- c. bench_function ( "indefinite string_alt ()" , |b| {
115
+ c. bench_function ( "indefinite string ()" , |b| {
83
116
b. iter ( || {
84
117
let mut decoder = Decoder :: new ( & indefinite_bytes) ;
85
- let _ = black_box ( decoder. str_alt ( ) ) ;
118
+ let _ = black_box ( decoder. string ( ) ) ;
86
119
} )
87
120
} ) ;
88
- }
89
121
90
- pub fn blob_benchmark ( c : & mut Criterion ) {
91
- // Indefinite length blob containing bytes corresponding to `indefinite-byte, chunked, on each comma`.
92
- let blob_indefinite_bytes = [
93
- 0x5f , 0x50 , 0x69 , 0x6e , 0x64 , 0x65 , 0x66 , 0x69 , 0x6e , 0x69 , 0x74 , 0x65 , 0x2d , 0x62 , 0x79 ,
94
- 0x74 , 0x65 , 0x2c , 0x49 , 0x20 , 0x63 , 0x68 , 0x75 , 0x6e , 0x6b , 0x65 , 0x64 , 0x2c , 0x4e , 0x20 ,
95
- 0x6f , 0x6e , 0x20 , 0x65 , 0x61 , 0x63 , 0x68 , 0x20 , 0x63 , 0x6f , 0x6d , 0x6d , 0x61 , 0xff ,
96
- ] ;
97
-
98
- c. bench_function ( "blob" , |b| {
122
+ c. bench_function ( "indefinite string_alt()" , |b| {
99
123
b. iter ( || {
100
- let mut decoder = Decoder :: new ( & blob_indefinite_bytes ) ;
101
- let _ = black_box ( decoder . blob ( ) ) ;
124
+ let mut decoder = minicbor :: decode :: Decoder :: new ( & indefinite_bytes ) ;
125
+ let _ = black_box ( string_alt ( & mut decoder ) ) ;
102
126
} )
103
127
} ) ;
104
128
}
105
129
106
- criterion_group ! (
107
- benches,
108
- string_benchmark,
109
- // str_benchmark blob_benchmark,
110
- // str_benchmark,
111
- ) ;
112
-
130
+ criterion_group ! ( benches, string_benchmark, str_benchmark, ) ;
113
131
criterion_main ! ( benches) ;
0 commit comments