@@ -46,11 +46,17 @@ pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
46
46
// - body, scan by 2 words at a time
47
47
// - the last remaining part, < 2 word size
48
48
let len = text. len ( ) ;
49
- let ptr = text. as_ptr ( ) ;
50
49
let usize_bytes = mem:: size_of :: < usize > ( ) ;
51
50
51
+ // Fast path for small slices
52
+ if len < 2 * usize_bytes {
53
+ return text. iter ( ) . position ( |elt| * elt == x) ;
54
+ }
55
+
52
56
// search up to an aligned boundary
57
+ let ptr = text. as_ptr ( ) ;
53
58
let mut offset = ptr. align_offset ( usize_bytes) ;
59
+
54
60
if offset > 0 {
55
61
offset = cmp:: min ( offset, len) ;
56
62
if let Some ( index) = text[ ..offset] . iter ( ) . position ( |elt| * elt == x) {
@@ -60,22 +66,19 @@ pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
60
66
61
67
// search the body of the text
62
68
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 ) ;
63
73
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 ;
76
79
}
77
- offset += usize_bytes * 2 ;
78
80
}
81
+ offset += usize_bytes * 2 ;
79
82
}
80
83
81
84
// Find the byte after the point the body loop stopped.
0 commit comments