From: Xinchen Hui Date: Sat, 17 Feb 2018 15:19:31 +0000 (+0800) Subject: Optimized strrev with SSSE3 X-Git-Tag: php-7.3.0alpha1~380 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c79f2de2cfe5a6b24a890269920d7714663d2ec9;p=php Optimized strrev with SSSE3 since strrev is not wildly used, and SSSE3 is defined default by some compiler, so won't try to do ifunc here. --- diff --git a/ext/standard/string.c b/ext/standard/string.c index 585495b715..2a79378c4b 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -3511,10 +3511,13 @@ PHP_FUNCTION(strtr) /* {{{ proto string strrev(string str) Reverse a string */ +#if ZEND_INTRIN_SSSE3_NATIVE +#include +#endif PHP_FUNCTION(strrev) { zend_string *str; - char *e, *p; + char *s, *e, *p; zend_string *n; ZEND_PARSE_PARAMETERS_START(1, 1) @@ -3524,10 +3527,24 @@ PHP_FUNCTION(strrev) n = zend_string_alloc(ZSTR_LEN(str), 0); p = ZSTR_VAL(n); - e = ZSTR_VAL(str) + ZSTR_LEN(str); - - while (--e >= ZSTR_VAL(str)) { - *p++ = *e; + s = ZSTR_VAL(str); + e = s + ZSTR_LEN(str); + --e; +#if ZEND_INTRIN_SSSE3_NATIVE + while (e - s > 15) { + const __m128i map = _mm_set_epi8( + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15); + const __m128i str = _mm_loadu_si128((__m128i *)(e - 15)); + _mm_storeu_si128((__m128i *)p, _mm_shuffle_epi8(str, map)); + p += 16; + e -= 16; + } +#endif + while (e >= s) { + *p++ = *e--; } *p = '\0';