@@ -84,17 +84,51 @@ static void rvalue_cache_insert_at(rvalue_cache *cache, int index, VALUE rstring
8484 cache -> entries [index ] = rstring ;
8585}
8686
87- static inline int rstring_cache_cmp (const char * str , const long length , VALUE rstring )
87+ static ALWAYS_INLINE () int rstring_cache_cmp (const char * str , const long length , VALUE rstring )
8888{
89+ #if defined(__BYTE_ORDER__ ) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) && defined(__has_builtin ) && __has_builtin (__builtin_bswap64 )
90+ const char * rptr ;
91+ long rstring_length ;
92+
93+ RSTRING_GETMEM (rstring , rptr , rstring_length );
94+
95+ if (length != rstring_length ) {
96+ return (int )(length - rstring_length );
97+ }
98+
99+ long i = 0 ;
100+
101+ for (; i + 8 <= length ; i += 8 ) {
102+ uint64_t a , b ;
103+ memcpy (& a , str + i , 8 );
104+ memcpy (& b , rptr + i , 8 );
105+ if (a != b ) {
106+ a = __builtin_bswap64 (a );
107+ b = __builtin_bswap64 (b );
108+ return (a < b ) ? -1 : 1 ;
109+ }
110+ }
111+
112+ for (; i < length ; i ++ ) {
113+ unsigned char ca = (unsigned char )str [i ];
114+ unsigned char cb = (unsigned char )rptr [i ];
115+ if (ca != cb ) {
116+ return (ca < cb ) ? -1 : 1 ;
117+ }
118+ }
119+
120+ return 0 ;
121+ #else
89122 long rstring_length = RSTRING_LEN (rstring );
90123 if (length == rstring_length ) {
91124 return memcmp (str , RSTRING_PTR (rstring ), length );
92125 } else {
93126 return (int )(length - rstring_length );
94127 }
128+ #endif
95129}
96130
97- static VALUE rstring_cache_fetch (rvalue_cache * cache , const char * str , const long length )
131+ static ALWAYS_INLINE () VALUE rstring_cache_fetch (rvalue_cache * cache , const char * str , const long length )
98132{
99133 int low = 0 ;
100134 int high = cache -> length - 1 ;
0 commit comments