11/* Fast unicode equal function optimized for dictobject.c and setobject.c */
22
3+ /* Return 1 if two unicode objects are equal, 0 if not.
4+ * unicode_eq() is called when the hash of two unicode objects is equal.
5+ */
6+ #if defined(__x86_64__ ) || defined(_M_X64 ) || defined(__i386__ ) || defined(_M_IX86 )
7+ # include <emmintrin.h>
8+ # define USE_SSE2 1
9+ #endif
10+
11+ static inline int
12+ unicode_memeq (const void * p1 , const void * p2 , size_t len ) {
13+ if (len == 0 ) return 1 ;
14+
15+ const uint8_t * u1 = (const uint8_t * )p1 ;
16+ const uint8_t * u2 = (const uint8_t * )p2 ;
17+
18+ switch (len ) {
19+ case 1 :
20+ return * u1 == * u2 ;
21+ case 2 :
22+ return * (const uint16_t * )u1 == * (const uint16_t * )u2 ;
23+ case 3 :
24+ return (* (const uint16_t * )u1 == * (const uint16_t * )u2 ) &&
25+ (* (const uint16_t * )(u1 + 1 ) == * (const uint16_t * )(u2 + 1 ));
26+ case 4 :
27+ return * (const uint32_t * )u1 == * (const uint32_t * )u2 ;
28+ case 5 :
29+ case 6 :
30+ case 7 :
31+ return (* (const uint32_t * )u1 == * (const uint32_t * )u2 ) &&
32+ (* (const uint32_t * )(u1 + len - 4 ) == * (const uint32_t * )(u2 + len - 4 ));
33+ case 8 :
34+ return * (const uint64_t * )u1 == * (const uint64_t * )u2 ;
35+ default :
36+ if (len <= 16 ) {
37+ return (* (const uint64_t * )u1 == * (const uint64_t * )u2 ) &&
38+ (* (const uint64_t * )(u1 + len - 8 ) == * (const uint64_t * )(u2 + len - 8 ));
39+ }
40+ #ifdef USE_SSE2
41+ if (len <= 32 ) {
42+ __m128i v1_a = _mm_loadu_si128 ((const __m128i * )u1 );
43+ __m128i v2_a = _mm_loadu_si128 ((const __m128i * )u2 );
44+ __m128i cmp_a = _mm_cmpeq_epi8 (v1_a , v2_a );
45+ int mask_a = _mm_movemask_epi8 (cmp_a );
46+
47+ __m128i v1_b = _mm_loadu_si128 ((const __m128i * )(u1 + len - 16 ));
48+ __m128i v2_b = _mm_loadu_si128 ((const __m128i * )(u2 + len - 16 ));
49+ __m128i cmp_b = _mm_cmpeq_epi8 (v1_b , v2_b );
50+ int mask_b = _mm_movemask_epi8 (cmp_b );
51+
52+ return (mask_a == 0xFFFF ) && (mask_b == 0xFFFF );
53+ }
54+ #endif
55+ return memcmp (p1 , p2 , len ) == 0 ;
56+ }
57+ }
58+
359/* Return 1 if two unicode objects are equal, 0 if not.
460 * unicode_eq() is called when the hash of two unicode objects is equal.
561 */
@@ -18,5 +74,5 @@ unicode_eq(PyObject *str1, PyObject *str2)
1874
1975 const void * data1 = PyUnicode_DATA (str1 );
2076 const void * data2 = PyUnicode_DATA (str2 );
21- return ( memcmp ( data1 , data2 , len * kind ) == 0 );
77+ return unicode_memeq ( data1 , data2 , len * kind );
2278}
0 commit comments