Speed up ClassDef/Coverage intersect methods

Just avoiding overhead as measured by Garret.
Should rewrite as dagger in the future and confirm that it has the
same benefits. Later on, rewrite as lfind() maybe.

Fixes https://github.com/harfbuzz/harfbuzz/issues/2826
This commit is contained in:
Behdad Esfahbod 2021-01-21 12:01:13 -07:00
parent 33368a12b7
commit 6463ee02d6

View File

@ -1251,8 +1251,9 @@ struct CoverageFormat1
{ {
/* TODO Speed up, using hb_set_next() and bsearch()? */ /* TODO Speed up, using hb_set_next() and bsearch()? */
unsigned int count = glyphArray.len; unsigned int count = glyphArray.len;
const HBGlyphID *arr = glyphArray.arrayZ;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (glyphs->has (glyphArray[i])) if (glyphs->has (arr[i]))
return true; return true;
return false; return false;
} }
@ -1356,18 +1357,21 @@ struct CoverageFormat2
bool intersects (const hb_set_t *glyphs) const bool intersects (const hb_set_t *glyphs) const
{ {
/* TODO Speed up, using hb_set_next() and bsearch()? */ /* TODO Speed up, using hb_set_next() and bsearch()? */
unsigned int count = rangeRecord.len; /* TODO Rewrite as dagger. */
for (unsigned int i = 0; i < count; i++) unsigned count = rangeRecord.len;
if (rangeRecord[i].intersects (glyphs)) const RangeRecord *arr = rangeRecord.arrayZ;
for (unsigned i = 0; i < count; i++)
if (arr[i].intersects (glyphs))
return true; return true;
return false; return false;
} }
bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
{ {
unsigned int i; /* TODO Rewrite as dagger. */
unsigned int count = rangeRecord.len; unsigned count = rangeRecord.len;
for (i = 0; i < count; i++) { const RangeRecord *arr = rangeRecord.arrayZ;
const RangeRecord &range = rangeRecord[i]; for (unsigned i = 0; i < count; i++) {
const RangeRecord &range = arr[i];
if (range.value <= index && if (range.value <= index &&
index < (unsigned int) range.value + (range.last - range.first) && index < (unsigned int) range.value + (range.last - range.first) &&
range.intersects (glyphs)) range.intersects (glyphs))
@ -1815,8 +1819,13 @@ struct ClassDefFormat1
if (hb_set_next (glyphs, &g)) return true; if (hb_set_next (glyphs, &g)) return true;
/* Fall through. */ /* Fall through. */
} }
/* TODO Speed up, using set overlap first? */
/* TODO Rewrite as dagger. */
HBUINT16 k; /* TODO(constexpr) use constructor to initialize. */
k = klass;
const HBUINT16 *arr = classValue.arrayZ;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (classValue[i] == klass && glyphs->has (startGlyph + i)) if (arr[i] == k && glyphs->has (startGlyph + i))
return true; return true;
return false; return false;
} }
@ -1984,8 +1993,13 @@ struct ClassDefFormat2
return true; return true;
/* Fall through. */ /* Fall through. */
} }
/* TODO Speed up, using set overlap first? */
/* TODO Rewrite as dagger. */
HBUINT16 k; /* TODO(constexpr) use constructor to initialize. */
k = klass;
const RangeRecord *arr = rangeRecord.arrayZ;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) if (arr[i].value == k && arr[i].intersects (glyphs))
return true; return true;
return false; return false;
} }