[ot-tags] Speed up hb_ot_tags_from_complex_language()

Part of https://github.com/harfbuzz/harfbuzz/issues/3591

2. All the subtag_matches outside the switch match long strings (>= 6 or so).
   As such, check the tag for such length before going into any of them.

benchmark-ot, before:

----------------------------------------------------------------------------------------------
Benchmark                                                    Time             CPU   Iterations
----------------------------------------------------------------------------------------------
BM_hb_ot_tags_from_script_and_language/COMMON zh_CN        172 ns          171 ns      4083155
BM_hb_ot_tags_from_script_and_language/COMMON en_US        120 ns          119 ns      5849947
BM_hb_ot_tags_from_script_and_language/LATIN en_US         113 ns          112 ns      5840326
BM_hb_ot_tags_from_script_and_language/COMMON none        4.66 ns         4.64 ns    151396224
BM_hb_ot_tags_from_script_and_language/LATIN none         4.66 ns         4.64 ns    149019593

After:

----------------------------------------------------------------------------------------------
Benchmark                                                    Time             CPU   Iterations
----------------------------------------------------------------------------------------------
BM_hb_ot_tags_from_script_and_language/COMMON zh_CN        112 ns          112 ns      6357763
BM_hb_ot_tags_from_script_and_language/COMMON en_US       60.5 ns         60.3 ns     11475091
BM_hb_ot_tags_from_script_and_language/LATIN en_US        54.9 ns         54.8 ns     12575690
BM_hb_ot_tags_from_script_and_language/COMMON none        4.61 ns         4.59 ns    152388450
BM_hb_ot_tags_from_script_and_language/LATIN none         4.66 ns         4.64 ns    151497600
This commit is contained in:
Behdad Esfahbod 2022-05-17 13:34:34 -06:00
parent 26d906b88b
commit 9baccb9860
2 changed files with 95 additions and 72 deletions

View File

@ -1009,6 +1009,24 @@ for initial, group in itertools.groupby ((lt_tags for lt_tags in [
key=lambda lt_tags: lt_tags[0].get_group ()):
complex_tags[initial] += group
# Calculate the min length of the subtags outside the switch
min_subtag_len = 100
for initial, items in sorted (complex_tags.items ()):
if initial != 'und':
continue
for lt, tags in items:
if not tags:
continue
subtag_len = 0
subtag_len += len(lt.script) if lt.script is not None else 0
subtag_len += len(lt.region) if lt.region is not None else 0
subtag_len += len(lt.variant) if lt.variant is not None else 0
min_subtag_len = min(subtag_len, min_subtag_len)
min_subtag_len += 1 # For initial '-'
print (' if (limit - lang_str > %d ||' % min_subtag_len)
print (" (limit - lang_str == %d && *lang_str == '-'))" % min_subtag_len)
print (' {')
for initial, items in sorted (complex_tags.items ()):
if initial != 'und':
continue
@ -1041,6 +1059,7 @@ for initial, items in sorted (complex_tags.items ()):
print (' *count = i;')
print (' return true;')
print (' }')
print (' }')
print (' switch (lang_str[0])')
print (' {')

View File

@ -1639,6 +1639,9 @@ hb_ot_tags_from_complex_language (const char *lang_str,
unsigned int *count /* IN/OUT */,
hb_tag_t *tags /* OUT */)
{
if (limit - lang_str > 5 ||
(limit - lang_str == 5 && *lang_str == '-'))
{
if (subtag_matches (lang_str, limit, "-fonnapa"))
{
/* Undetermined; North American Phonetic Alphabet */
@ -1702,6 +1705,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
*count = 1;
return true;
}
}
switch (lang_str[0])
{
case 'a':