Hand-code bsearch in the hot inner loop.

Saves another 3 / 4 percent with Amiri.
This commit is contained in:
Behdad Esfahbod 2013-04-19 14:33:17 -04:00
parent 797d76d07f
commit 8659c63608
1 changed files with 15 additions and 14 deletions

View File

@ -949,21 +949,22 @@ template <typename Type>
struct SortedArrayOf : ArrayOf<Type> { struct SortedArrayOf : ArrayOf<Type> {
template <typename SearchType> template <typename SearchType>
inline int search (const SearchType &x) const { inline int search (const SearchType &x) const
unsigned int count = this->len; {
/* Linear search is *much* faster for small counts. */ /* Hand-coded bsearch here since this is in the hot inner loop. */
if (likely (count < 32)) { int min = 0, max = (int) this->len - 1;
for (unsigned int i = 0; i < count; i++) while (min <= max)
if (this->array[i].cmp (x) == 0) {
return i; int mid = (min + max) / 2;
return -1; int c = this->array[mid].cmp (x);
} else { if (c < 0)
struct Cmp { max = mid - 1;
static int cmp (const SearchType *a, const Type *b) { return b->cmp (*a); } else if (c > 0)
}; min = mid + 1;
const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof (this->array[0]), (hb_compare_func_t) Cmp::cmp); else
return p ? p - this->array : -1; return mid;
} }
return -1;
} }
}; };