[set] Optimize const page_for() using last_page_lookup caching

Similar to previous commit.

This speeds up SetLookup benchmark by 50%, but that's because that
lookup always hits the same page...
This commit is contained in:
Behdad Esfahbod 2022-04-29 13:04:36 -06:00
parent c283e41ce3
commit 067225a86d
1 changed files with 19 additions and 5 deletions

View File

@ -908,11 +908,25 @@ struct hb_bit_set_t
} }
const page_t *page_for (hb_codepoint_t g) const const page_t *page_for (hb_codepoint_t g) const
{ {
page_map_t key = {get_major (g)}; unsigned major = get_major (g);
const page_map_t *found = page_map.bsearch (key);
if (found) /* The extra page_map length is necessary; can't just rely on vector here,
return &pages[found->index]; * since the next check would be tricked because a null page also has
return nullptr; * major==0, which we can't distinguish from an actualy major==0 page... */
if (likely (last_page_lookup < page_map.length))
{
auto &cached_page = page_map.arrayZ[last_page_lookup];
if (cached_page.major == major)
return &pages[cached_page.index];
}
page_map_t key = {major};
unsigned int i;
if (!page_map.bfind (key, &i))
return nullptr;
last_page_lookup = i;
return &pages[page_map[i].index];
} }
page_t &page_at (unsigned int i) { return pages[page_map[i].index]; } page_t &page_at (unsigned int i) { return pages[page_map[i].index]; }
const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; } const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; }