1
- #![ cfg_attr( feature = "nightly" , feature( portable_simd) ) ]
2
1
#![ cfg_attr( feature = "nightly" , feature( test) ) ]
3
2
4
- #[ cfg( feature = "nightly " ) ]
5
- pub use nightly :: encode_str;
3
+ #[ cfg( target_arch = "aarch64 " ) ]
4
+ pub use aarch64 :: encode_str;
6
5
7
- #[ cfg( feature = "nightly " ) ]
8
- mod nightly ;
6
+ #[ cfg( target_arch = "aarch64 " ) ]
7
+ mod aarch64 ;
9
8
10
9
const BB : u8 = b'b' ; // \x08
11
10
const TT : u8 = b't' ; // \x09
@@ -92,18 +91,24 @@ macro_rules! tri {
92
91
} ;
93
92
}
94
93
95
- #[ cfg( not( feature = "nightly" ) ) ]
96
- pub fn encode_str < S : AsRef < str > > ( input : S , writer : & mut String ) {
97
- let writer = unsafe { writer. as_mut_vec ( ) } ;
94
+ #[ cfg_attr( target_arch = "aarch64" , allow( unused) ) ]
95
+ #[ inline]
96
+ fn encode_str_fallback < S : AsRef < str > > ( input : S ) -> String {
97
+ let mut output = String :: with_capacity ( input. as_ref ( ) . len ( ) + 2 ) ;
98
+ let writer = unsafe { output. as_mut_vec ( ) } ;
98
99
writer. push ( b'"' ) ;
99
- encode_str_inner ( input, writer) ;
100
+ encode_str_inner ( input. as_ref ( ) . as_bytes ( ) , writer) ;
100
101
writer. push ( b'"' ) ;
102
+ output
103
+ }
104
+
105
+ #[ cfg( not( target_arch = "aarch64" ) ) ]
106
+ pub fn encode_str < S : AsRef < str > > ( input : S ) -> String {
107
+ encode_str_fallback ( input)
101
108
}
102
109
103
110
#[ inline]
104
- pub ( crate ) fn encode_str_inner < S : AsRef < str > > ( input : S , writer : & mut Vec < u8 > ) {
105
- let input = input. as_ref ( ) ;
106
- let bytes = input. as_bytes ( ) ;
111
+ pub ( crate ) fn encode_str_inner ( bytes : & [ u8 ] , writer : & mut Vec < u8 > ) {
107
112
let mut start = 0 ;
108
113
for ( i, & byte) in bytes. iter ( ) . enumerate ( ) {
109
114
let escape = ESCAPE [ byte as usize ] ;
@@ -112,7 +117,7 @@ pub(crate) fn encode_str_inner<S: AsRef<str>>(input: S, writer: &mut Vec<u8>) {
112
117
}
113
118
114
119
if start < i {
115
- writer. extend_from_slice ( & input . as_bytes ( ) [ start..i] ) ;
120
+ writer. extend_from_slice ( & bytes [ start..i] ) ;
116
121
}
117
122
118
123
let char_escape = CharEscape :: from_escape_table ( escape, byte) ;
@@ -124,7 +129,7 @@ pub(crate) fn encode_str_inner<S: AsRef<str>>(input: S, writer: &mut Vec<u8>) {
124
129
if start == bytes. len ( ) {
125
130
return ;
126
131
}
127
- writer. extend_from_slice ( & input . as_bytes ( ) [ start..] ) ;
132
+ writer. extend_from_slice ( & bytes [ start..] ) ;
128
133
}
129
134
130
135
/// Writes a character escape code to the specified writer.
@@ -161,9 +166,7 @@ fn write_char_escape(writer: &mut Vec<u8>, char_escape: CharEscape) {
161
166
#[ test]
162
167
fn test_escape_ascii_json_string ( ) {
163
168
let fixture = r#"abcdefghijklmnopqrstuvwxyz .*? hello world escape json string"# ;
164
- let mut buf = String :: new ( ) ;
165
- encode_str ( fixture, & mut buf) ;
166
- assert_eq ! ( buf, serde_json:: to_string( fixture) . unwrap( ) ) ;
169
+ assert_eq ! ( encode_str( fixture) , serde_json:: to_string( fixture) . unwrap( ) ) ;
167
170
}
168
171
169
172
#[ test]
@@ -183,10 +186,9 @@ fn test_escape_json_string() {
183
186
fixture. push_str ( "normal string" ) ;
184
187
fixture. push ( '😊' ) ;
185
188
fixture. push_str ( "中文 English 🚀 \n ❓ 𝄞" ) ;
186
- let mut buf = String :: new ( ) ;
187
- encode_str ( fixture. as_str ( ) , & mut buf) ;
189
+ encode_str ( fixture. as_str ( ) ) ;
188
190
assert_eq ! (
189
- buf ,
191
+ encode_str ( fixture . as_str ( ) ) ,
190
192
serde_json:: to_string( fixture. as_str( ) ) . unwrap( ) ,
191
193
"fixture: {:?}" ,
192
194
fixture
@@ -197,30 +199,21 @@ fn test_escape_json_string() {
197
199
mod bench {
198
200
extern crate test;
199
201
200
- use std:: hint:: black_box;
201
-
202
202
use test:: Bencher ;
203
203
204
204
const FIXTURE : & str = include_str ! ( "../cal.com.tsx" ) ;
205
205
206
206
#[ bench]
207
207
fn bench_simd_encode ( b : & mut Bencher ) {
208
208
b. iter ( || {
209
- let mut buf = String :: new ( ) ;
210
- black_box ( super :: encode_str ( FIXTURE , & mut buf) ) ;
211
- buf
209
+ super :: encode_str ( FIXTURE ) ;
212
210
} ) ;
213
211
}
214
212
215
213
#[ bench]
216
214
fn bench_encode ( b : & mut Bencher ) {
217
215
b. iter ( || {
218
- let mut buf = String :: new ( ) ;
219
- let writer = unsafe { buf. as_mut_vec ( ) } ;
220
- writer. push ( b'"' ) ;
221
- black_box ( super :: encode_str_inner ( FIXTURE , writer) ) ;
222
- writer. push ( b'"' ) ;
223
- buf
216
+ super :: encode_str_fallback ( FIXTURE ) ;
224
217
} ) ;
225
218
}
226
219
}
0 commit comments