@@ -46,11 +46,17 @@ pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
4646 // - body, scan by 2 words at a time
4747 // - the last remaining part, < 2 word size
4848 let len = text. len ( ) ;
49- let ptr = text. as_ptr ( ) ;
5049 let usize_bytes = mem:: size_of :: < usize > ( ) ;
5150
51+ // Fast path for small slices
52+ if len < 2 * usize_bytes {
53+ return text. iter ( ) . position ( |elt| * elt == x) ;
54+ }
55+
5256 // search up to an aligned boundary
57+ let ptr = text. as_ptr ( ) ;
5358 let mut offset = ptr. align_offset ( usize_bytes) ;
59+
5460 if offset > 0 {
5561 offset = cmp:: min ( offset, len) ;
5662 if let Some ( index) = text[ ..offset] . iter ( ) . position ( |elt| * elt == x) {
@@ -60,22 +66,19 @@ pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
6066
6167 // search the body of the text
6268 let repeated_x = repeat_byte ( x) ;
69+ while offset <= len - 2 * usize_bytes {
70+ unsafe {
71+ let u = * ( ptr. add ( offset) as * const usize ) ;
72+ let v = * ( ptr. add ( offset + usize_bytes) as * const usize ) ;
6373
64- if len >= 2 * usize_bytes {
65- while offset <= len - 2 * usize_bytes {
66- unsafe {
67- let u = * ( ptr. add ( offset) as * const usize ) ;
68- let v = * ( ptr. add ( offset + usize_bytes) as * const usize ) ;
69-
70- // break if there is a matching byte
71- let zu = contains_zero_byte ( u ^ repeated_x) ;
72- let zv = contains_zero_byte ( v ^ repeated_x) ;
73- if zu || zv {
74- break ;
75- }
74+ // break if there is a matching byte
75+ let zu = contains_zero_byte ( u ^ repeated_x) ;
76+ let zv = contains_zero_byte ( v ^ repeated_x) ;
77+ if zu || zv {
78+ break ;
7679 }
77- offset += usize_bytes * 2 ;
7880 }
81+ offset += usize_bytes * 2 ;
7982 }
8083
8184 // Find the byte after the point the body loop stopped.
0 commit comments