Skip to content

Commit

Permalink
Use binary search for cp932ext*_ucs_table lookups (#12712)
Browse files Browse the repository at this point in the history
* Use binary search for cp932ext*_ucs_table lookups

A large amount of time is spent doing a linear search through these
tables in the CP932 encoding. Instead of that, we can add sorted
versions of these tables that also store the index of the non-sorted
version and perform a binary search on those sorted versions.

This reduces the time spent from 1.54s to 0.91s for the reference
benchmark [1].

[1] #12684 (comment)

* Fix search bounds
  • Loading branch information
nielsdos authored Nov 18, 2023
1 parent 3ad422e commit 91279cf
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 20 deletions.
53 changes: 33 additions & 20 deletions ext/mbstring/libmbfl/filters/mbfilter_cjk.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,23 @@ int mbfl_bisec_srch2(int w, const unsigned short tbl[], int n)
return -1;
}

static const unsigned short *mbfl_binary_search_paired_sorted_table(uint32_t w, const unsigned short tbl[][2], int n)
{
int r = n;
int l = 0;
while (l < r) {
int probe = (l + r) >> 1;
if (w < tbl[probe][0]) {
r = probe;
} else if (w > tbl[probe][0]) {
l = probe + 1;
} else {
return &tbl[probe][1];
}
}
return NULL;
}

#define SJIS_ENCODE(c1,c2,s1,s2) \
do { \
s1 = ((c1 - 1) >> 1) + ((c1) < 0x5F ? 0x71 : 0xB1); \
Expand Down Expand Up @@ -7639,18 +7656,16 @@ static void mb_wchar_to_cp932(uint32_t *in, size_t len, mb_convert_buf *buf, boo
}

if (!s1 || (s1 >= 0x8080 && !s2)) { /* not found or X 0212 */
for (unsigned int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) {
if (cp932ext1_ucs_table[i] == w) {
s1 = ((i/94 + 0x2D) << 8) + (i%94 + 0x21);
goto emit_output;
}
const unsigned short *lookup = mbfl_binary_search_paired_sorted_table(w, cp932ext1_ucs_table_paired_sorted, sizeof(cp932ext1_ucs_table_paired_sorted) / sizeof(*cp932ext1_ucs_table_paired_sorted));
if (lookup) {
s1 = ((*lookup/94 + 0x2D) << 8) + (*lookup%94 + 0x21);
goto emit_output;
}

for (unsigned int i = 0; i < cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; i++) {
if (cp932ext3_ucs_table[i] == w) {
s1 = ((i/94 + 0x93) << 8) + (i%94 + 0x21);
goto emit_output;
}
lookup = mbfl_binary_search_paired_sorted_table(w, cp932ext3_ucs_table_paired_sorted, sizeof(cp932ext3_ucs_table_paired_sorted) / sizeof(*cp932ext3_ucs_table_paired_sorted));
if (lookup) {
s1 = ((*lookup/94 + 0x93) << 8) + (*lookup%94 + 0x21);
goto emit_output;
}

MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp932);
Expand Down Expand Up @@ -7718,18 +7733,16 @@ static void mb_wchar_to_sjiswin(uint32_t *in, size_t len, mb_convert_buf *buf, b
}

if (!s1 || (s1 >= 0x8080 && !s2)) { /* not found or X 0212 */
for (unsigned int i = 0; i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) {
if (cp932ext1_ucs_table[i] == w) {
s1 = ((i/94 + 0x2D) << 8) + (i%94 + 0x21);
goto emit_output;
}
const unsigned short *lookup = mbfl_binary_search_paired_sorted_table(w, cp932ext1_ucs_table_paired_sorted, sizeof(cp932ext1_ucs_table_paired_sorted) / sizeof(*cp932ext1_ucs_table_paired_sorted));
if (lookup) {
s1 = ((*lookup/94 + 0x2D) << 8) + (*lookup%94 + 0x21);
goto emit_output;
}

for (unsigned int i = 0; i < cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; i++) {
if (cp932ext3_ucs_table[i] == w) {
s1 = ((i/94 + 0x93) << 8) + (i%94 + 0x21);
goto emit_output;
}
lookup = mbfl_binary_search_paired_sorted_table(w, cp932ext3_ucs_table_paired_sorted, sizeof(cp932ext3_ucs_table_paired_sorted) / sizeof(*cp932ext3_ucs_table_paired_sorted));
if (lookup) {
s1 = ((*lookup/94 + 0x93) << 8) + (*lookup%94 + 0x21);
goto emit_output;
}

MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_cp932);
Expand Down
8 changes: 8 additions & 0 deletions ext/mbstring/libmbfl/filters/unicode_table_cp932_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ const unsigned short cp932ext1_ucs_table[] = {
const int cp932ext1_ucs_table_min = (13 - 1)*94;
const int cp932ext1_ucs_table_max = (13 - 1)*94 + (sizeof (cp932ext1_ucs_table) / sizeof (unsigned short));

const unsigned short cp932ext1_ucs_table_paired_sorted[][2] = {
{0x0,30}, {0x2116,65}, {0x2121,67}, {0x2160,20}, {0x2161,21}, {0x2162,22}, {0x2163,23}, {0x2164,24}, {0x2165,25}, {0x2166,26}, {0x2167,27}, {0x2168,28}, {0x2169,29}, {0x2211,83}, {0x221a,84}, {0x221f,87}, {0x2220,86}, {0x2229,90}, {0x222a,91}, {0x222b,81}, {0x222e,82}, {0x2235,89}, {0x2252,79}, {0x2261,80}, {0x22a5,85}, {0x22bf,88}, {0x2460,0}, {0x2461,1}, {0x2462,2}, {0x2463,3}, {0x2464,4}, {0x2465,5}, {0x2466,6}, {0x2467,7}, {0x2468,8}, {0x2469,9}, {0x246a,10}, {0x246b,11}, {0x246c,12}, {0x246d,13}, {0x246e,14}, {0x246f,15}, {0x2470,16}, {0x2471,17}, {0x2472,18}, {0x2473,19}, {0x301d,63}, {0x301f,64}, {0x3231,73}, {0x3232,74}, {0x3239,75}, {0x32a4,68}, {0x32a5,69}, {0x32a6,70}, {0x32a7,71}, {0x32a8,72}, {0x3303,37}, {0x330d,41}, {0x3314,32}, {0x3318,35}, {0x3322,33}, {0x3323,43}, {0x3326,42}, {0x3327,36}, {0x332b,44}, {0x3336,38}, {0x333b,46}, {0x3349,31}, {0x334a,45}, {0x334d,34}, {0x3351,39}, {0x3357,40}, {0x337b,62}, {0x337c,78}, {0x337d,77}, {0x337e,76}, {0x338e,50}, {0x338f,51}, {0x339c,47}, {0x339d,48}, {0x339e,49}, {0x33a1,53}, {0x33c4,52}, {0x33cd,66}
};

const unsigned short cp932ext2_ucs_table[] = {
/* ku 89 */
0x7E8A,0x891C,0x9348,0x9288,0x84DC,0x4FC9,0x70BB,0x6631,
Expand Down Expand Up @@ -167,4 +171,8 @@ const unsigned short cp932ext3_ucs_table[] = {
const int cp932ext3_ucs_table_min = (115 - 1)*94;
const int cp932ext3_ucs_table_max = (115 - 1)*94 + (sizeof (cp932ext3_ucs_table) / sizeof (unsigned short));

const unsigned short cp932ext3_ucs_table_paired_sorted[][2] = {
{0x2116,25}, {0x2121,26}, {0x2160,10}, {0x2161,11}, {0x2162,12}, {0x2163,13}, {0x2164,14}, {0x2165,15}, {0x2166,16}, {0x2167,17}, {0x2168,18}, {0x2169,19}, {0x2170,0}, {0x2171,1}, {0x2172,2}, {0x2173,3}, {0x2174,4}, {0x2175,5}, {0x2176,6}, {0x2177,7}, {0x2178,8}, {0x2179,9}, {0x2235,27}, {0x3231,24}, {0x4e28,40}, {0x4ee1,41}, {0x4efc,42}, {0x4f00,43}, {0x4f03,44}, {0x4f39,45}, {0x4f56,46}, {0x4f8a,48}, {0x4f92,47}, {0x4f94,50}, {0x4f9a,49}, {0x4fc9,33}, {0x4fcd,51}, {0x4fff,54}, {0x501e,55}, {0x5022,53}, {0x5040,52}, {0x5042,58}, {0x5046,56}, {0x5070,57}, {0x5094,59}, {0x50d8,61}, {0x50f4,60}, {0x514a,62}, {0x5164,63}, {0x519d,64}, {0x51be,65}, {0x51ec,66}, {0x5215,67}, {0x529c,68}, {0x52a6,69}, {0x52af,243}, {0x52c0,70}, {0x52db,71}, {0x5300,72}, {0x5307,73}, {0x5324,74}, {0x5372,75}, {0x5393,76}, {0x53b2,77}, {0x53dd,78}, {0x548a,81}, {0x549c,80}, {0x54a9,82}, {0x54ff,83}, {0x5586,84}, {0x5759,85}, {0x5765,86}, {0x57ac,87}, {0x57c7,89}, {0x57c8,88}, {0x589e,92}, {0x58b2,93}, {0x590b,94}, {0x5953,95}, {0x595b,96}, {0x595d,97}, {0x5963,98}, {0x59a4,99}, {0x59ba,100}, {0x5b56,101}, {0x5bc0,102}, {0x5bd8,104}, {0x5bec,105}, {0x5c1e,106}, {0x5ca6,107}, {0x5cba,108}, {0x5cf5,109}, {0x5d27,110}, {0x5d42,113}, {0x5d53,111}, {0x5d6d,114}, {0x5db8,115}, {0x5db9,116}, {0x5dd0,117}, {0x5f21,118}, {0x5f34,119}, {0x5f45,39}, {0x5f67,120}, {0x5fb7,121}, {0x5fde,122}, {0x605d,123}, {0x6085,124}, {0x608a,125}, {0x60d5,127}, {0x60de,126}, {0x60f2,129}, {0x6111,130}, {0x6120,128}, {0x6130,132}, {0x6137,131}, {0x6198,133}, {0x6213,134}, {0x62a6,135}, {0x63f5,136}, {0x6460,137}, {0x649d,138}, {0x64ce,139}, {0x654e,140}, {0x6600,141}, {0x6609,144}, {0x6615,142}, {0x661e,146}, {0x6624,147}, {0x662e,145}, {0x6631,35}, {0x663b,143}, {0x6657,149}, {0x6659,150}, {0x6665,148}, {0x6673,152}, {0x6699,153}, {0x66a0,154}, {0x66b2,155}, {0x66bf,156}, {0x66fa,157}, {0x66fb,38}, {0x670e,158}, {0x6766,160}, {0x67bb,161}, {0x67c0,163}, {0x6801,164}, {0x6844,165}, {0x6852,162}, {0x68c8,36}, {0x68cf,166}, {0x6968,168}, {0x6998,170}, {0x69e2,171}, {0x6a30,172}, {0x6a46,174}, {0x6a6b,173}, {0x6a73,175}, {0x6a7e,176}, {0x6ae2,177}, {0x6ae4,178}, {0x6bd6,179}, {0x6c3f,180}, {0x6c5c,181}, {0x6c6f,183}, {0x6c86,182}, {0x6cda,184}, {0x6d04,185}, {0x6d6f,187}, {0x6d87,186}, {0x6d96,188}, {0x6dac,189}, {0x6dcf,190}, {0x6df2,192}, {0x6df8,191}, {0x6dfc,193}, {0x6e27,196}, {0x6e39,194}, {0x6e3c,197}, {0x6e5c,195}, {0x6ebf,198}, {0x6f88,199}, {0x6fb5,200}, {0x6ff5,201}, {0x7005,202}, {0x7007,203}, {0x7028,204}, {0x7085,205}, {0x70ab,206}, {0x70bb,34}, {0x7104,208}, {0x710f,207}, {0x7146,210}, {0x7147,211}, {0x715c,209}, {0x71c1,213}, {0x71fe,214}, {0x72b1,215}, {0x72be,216}, {0x7324,217}, {0x7377,219}, {0x73bd,220}, {0x73c9,221}, {0x73d2,224}, {0x73d6,222}, {0x73e3,223}, {0x73f5,226}, {0x7407,225}, {0x7426,227}, {0x7429,229}, {0x742a,228}, {0x742e,230}, {0x7462,231}, {0x7489,232}, {0x749f,233}, {0x7501,234}, {0x752f,103}, {0x756f,235}, {0x7682,236}, {0x769b,239}, {0x769c,237}, {0x769e,238}, {0x76a6,240}, {0x7746,242}, {0x7821,244}, {0x784e,245}, {0x7864,246}, {0x787a,247}, {0x7930,248}, {0x7994,252}, {0x799b,254}, {0x7ad1,255}, {0x7ae7,256}, {0x7aeb,258}, {0x7b9e,259}, {0x7d48,261}, {0x7d5c,262}, {0x7da0,264}, {0x7db7,263}, {0x7dd6,265}, {0x7e52,266}, {0x7e8a,28}, {0x7f47,267}, {0x7fa1,268}, {0x8301,270}, {0x8362,271}, {0x837f,272}, {0x83c7,273}, {0x83f6,274}, {0x8448,275}, {0x84b4,276}, {0x84dc,32}, {0x8553,277}, {0x8559,278}, {0x856b,279}, {0x85b0,281}, {0x8807,284}, {0x88f5,285}, {0x891c,29}, {0x8a12,286}, {0x8a37,287}, {0x8a79,288}, {0x8aa7,289}, {0x8abe,290}, {0x8adf,291}, {0x8af6,293}, {0x8b53,294}, {0x8b7f,295}, {0x8cf0,296}, {0x8cf4,297}, {0x8d12,298}, {0x8d76,299}, {0x8ecf,301}, {0x9067,304}, {0x90de,305}, {0x9115,307}, {0x9127,308}, {0x91d7,310}, {0x91da,309}, {0x91de,311}, {0x91e4,314}, {0x91e5,315}, {0x91ed,312}, {0x91ee,313}, {0x9206,316}, {0x920a,318}, {0x9210,317}, {0x9239,325}, {0x923a,319}, {0x923c,321}, {0x9240,320}, {0x924e,322}, {0x9251,324}, {0x9259,323}, {0x9267,326}, {0x9277,328}, {0x9278,329}, {0x9288,31}, {0x92a7,327}, {0x92d0,333}, {0x92d3,337}, {0x92d5,335}, {0x92d7,331}, {0x92d9,332}, {0x92e0,336}, {0x92e7,330}, {0x92f9,37}, {0x92fb,340}, {0x92ff,343}, {0x9302,345}, {0x931d,344}, {0x931e,342}, {0x9321,339}, {0x9325,338}, {0x9348,30}, {0x9357,347}, {0x9370,346}, {0x93a4,348}, {0x93c6,349}, {0x93de,350}, {0x93f8,351}, {0x9431,352}, {0x9445,353}, {0x9448,354}, {0x9592,355}, {0x969d,358}, {0x96af,359}, {0x9733,360}, {0x973b,361}, {0x9743,362}, {0x974d,363}, {0x974f,364}, {0x9751,365}, {0x9755,366}, {0x9857,367}, {0x9865,368}, {0x9927,371}, {0x999e,373}, {0x9a4e,374}, {0x9ad9,375}, {0x9adc,376}, {0x9b72,378}, {0x9b75,377}, {0x9b8f,379}, {0x9bb1,380}, {0x9bbb,381}, {0x9c00,382}, {0x9d6b,384}, {0x9d70,383}, {0x9e19,386}, {0x9ed1,387}, {0xf929,159}, {0xf9dc,356}, {0xfa0e,79}, {0xfa0f,90}, {0xfa10,91}, {0xfa11,112}, {0xfa12,151}, {0xfa13,167}, {0xfa14,169}, {0xfa15,212}, {0xfa16,218}, {0xfa17,241}, {0xfa18,249}, {0xfa19,250}, {0xfa1a,251}, {0xfa1b,253}, {0xfa1c,257}, {0xfa1d,260}, {0xfa1e,269}, {0xfa1f,280}, {0xfa20,282}, {0xfa21,283}, {0xfa22,292}, {0xfa23,300}, {0xfa24,302}, {0xfa25,303}, {0xfa26,306}, {0xfa27,334}, {0xfa28,341}, {0xfa29,357}, {0xfa2a,369}, {0xfa2b,370}, {0xfa2c,372}, {0xfa2d,385}, {0xff02,23}, {0xff07,22}, {0xffe2,20}, {0xffe4,21}
};

#endif /* UNICODE_TABLE_CP932_EXT_H */

0 comments on commit 91279cf

Please sign in to comment.