Search Non ASCII with words
通常上のようなケースではベクトル化されないので自分でやります。具体的にはバイト列を 1 バイトごと調べていたのを、ワード単位で判定するようにします。アライメントを揃えないと落ちたり遅くなったりするので前処理と、端数対策で後処理を。これで 1000 文字を 100 万回調べるのに 2.5 秒と、大幅な高速化が可能になります。(これが akr さんの r15129 の変更)
#if SIZEOF_VOIDP == 8 # define NONASCII_MASK 0x8080808080808080LL #elif SIZEOF_VOIDP == 4 # define NONASCII_MASK 0x80808080UL #endif const char * search_nonascii_words(const char *p, const char *e) { intptr_t align; if (SIZEOF_VOIDP * 2 <= e - p) { const intptr_t lowbits = SIZEOF_VOIDP - 1; const intptr_t *wp, *we; align = (intptr_t)p & (SIZEOF_VOIDP - 1); switch (align) { #if SIZEOF_VOIDP == 8 case 7: if (!isascii(*p)) return p; ++p; case 6: if (!isascii(*p)) return p; ++p; case 5: if (!isascii(*p)) return p; ++p; case 4: if (!isascii(*p)) return p; ++p; #endif case 3: if (!isascii(*p)) return p; ++p; case 2: if (!isascii(*p)) return p; ++p; case 1: if (!isascii(*p)) return p; ++p; } wp = (const intptr_t *)(~lowbits & ((intptr_t)p + lowbits)); we = (const intptr_t *)(~lowbits & (intptr_t)e); for (; wp < we; ++wp) { if (*wp & NONASCII_MASK) break; } p = (const char *)wp; switch (e - p) { #if SIZEOF_VOIDP == 8 case 7: if (!isascii(*p)) return p; ++p; case 6: if (!isascii(*p)) return p; ++p; case 5: if (!isascii(*p)) return p; ++p; case 4: if (!isascii(*p)) return p; ++p; #endif case 3: if (!isascii(*p)) return p; ++p; case 2: if (!isascii(*p)) return p; ++p; case 1: if (!isascii(*p)) return p; ++p; } } else { switch (e - p) { #if SIZEOF_VOIDP == 8 case 15: if (!isascii(*p)) return p; ++p; case 14: if (!isascii(*p)) return p; ++p; case 13: if (!isascii(*p)) return p; ++p; case 12: if (!isascii(*p)) return p; ++p; case 11: if (!isascii(*p)) return p; ++p; case 10: if (!isascii(*p)) return p; ++p; case 9: if (!isascii(*p)) return p; ++p; case 8: if (!isascii(*p)) return p; ++p; #endif case 7: if (!isascii(*p)) return p; ++p; case 6: if (!isascii(*p)) return p; ++p; case 5: if (!isascii(*p)) return p; ++p; case 4: if (!isascii(*p)) return p; ++p; case 3: if (!isascii(*p)) return p; ++p; case 2: if (!isascii(*p)) return p; ++p; case 1: if (!isascii(*p)) return p; } return NULL; } }