Skip to content

Commit 031a392

Browse files
committed
different implementation of parse_unsigned
1 parent 5663210 commit 031a392

File tree

1 file changed

+18
-28
lines changed

1 file changed

+18
-28
lines changed

include/boost/json/detail/sse2.hpp

+18-28
Original file line numberDiff line numberDiff line change
@@ -315,34 +315,7 @@ inline int count_digits( char const* p ) noexcept
315315

316316
inline uint64_t parse_unsigned( uint64_t r, char const * p, std::size_t n ) noexcept
317317
{
318-
while( n >= 4 )
319-
{
320-
// faster on on clang for x86,
321-
// slower on gcc
322-
#ifdef __clang__
323-
r = r * 10 + p[0] - '0';
324-
r = r * 10 + p[1] - '0';
325-
r = r * 10 + p[2] - '0';
326-
r = r * 10 + p[3] - '0';
327-
#else
328-
uint32_t v;
329-
std::memcpy( &v, p, 4 );
330-
endian::native_to_little_inplace(v);
331-
332-
v -= 0x30303030;
333-
334-
unsigned w0 = v & 0xFF;
335-
unsigned w1 = (v >> 8) & 0xFF;
336-
unsigned w2 = (v >> 16) & 0xFF;
337-
unsigned w3 = (v >> 24);
338-
339-
r = (((r * 10 + w0) * 10 + w1) * 10 + w2) * 10 + w3;
340-
#endif
341-
p += 4;
342-
n -= 4;
343-
}
344-
345-
switch( n )
318+
switch( n & 3 )
346319
{
347320
case 0:
348321
break;
@@ -359,6 +332,23 @@ inline uint64_t parse_unsigned( uint64_t r, char const * p, std::size_t n ) noex
359332
r = r * 10 + p[2] - '0';
360333
break;
361334
}
335+
336+
auto const e = p + n;
337+
p += n & 3;
338+
while( p != e )
339+
{
340+
uint32_t v;
341+
std::memcpy( &v, p, 4 );
342+
endian::native_to_little_inplace(v);
343+
344+
v = (v & 0x0F0F0F0F) * 2561 >> 8;
345+
v = (v & 0x00FF00FF) * 6553601 >> 16;
346+
347+
r = r * 10000 + v;
348+
349+
p += 4;
350+
}
351+
362352
return r;
363353
}
364354

0 commit comments

Comments
 (0)