Skip to content

Commit

Permalink
Add shar's algorithm
Browse files Browse the repository at this point in the history
This is based on the D version by Alex Muscar, which was based on an
implementation in Writing Efficient Programs by Jon L. Bentley. It was
originally published by Knuth and is attributed to Shar.

https://muscar.eu/shar-binary-search-meta.html

Previously, I had mistaken the monobound binary search for a loop
version of Shar's algorithm, but after looking at them more deeply, I
realize that they are subtly different.

On my Ryzen 7 5800X, this will outperform the monobound binary search on
array sizes that are powers of 2 or near powers of 2.

Signed-off-by: Richard Yao <[email protected]>
  • Loading branch information
ryao committed May 27, 2023
1 parent ff7c12a commit 6b8617b
Showing 1 changed file with 34 additions and 0 deletions.
34 changes: 34 additions & 0 deletions binary_search.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright (C) 2014-2021 Igor van den Hoven [email protected]
Copyright (C) 2023 Zettabyte Software LLC.
*/

/*
Expand Down Expand Up @@ -523,6 +524,36 @@ int adaptive_binary_search(int *array, unsigned int array_size, int key)
return -1;
}

int shar_binary_search(int *array, unsigned int array_size, int key)
{
unsigned int i;

switch (array_size)
{
default:
unsigned int u = sizeof (array_size) * 8 - __builtin_clz(2U*array_size-1U) - 2;
unsigned int p = 1U << (u);
i = (array[p] <= key) * (array_size - p);

++checks;

while (p >>= 1) {
++checks;
if (array[i + p] <= key)
i += p;
}
break;
case 1:
i = 0;
break;
case 0:
return -1;
}

++checks;
return (array[i] == key) ? i : -1;
}

// benchmark

long long utime()
Expand Down Expand Up @@ -683,6 +714,7 @@ int main(int argc, char **argv)
run(monobound_quaternary_search);
run(monobound_interpolated_search);
run(adaptive_binary_search);
run(shar_binary_search);

// uneven distribution

Expand All @@ -701,6 +733,7 @@ int main(int argc, char **argv)
run(monobound_binary_search);
run(monobound_interpolated_search);
run(adaptive_binary_search);
run(shar_binary_search);

// sequential access, check stability while at it

Expand All @@ -726,6 +759,7 @@ int main(int argc, char **argv)
run(monobound_quaternary_search);
run(monobound_interpolated_search);
run(adaptive_binary_search);
run(shar_binary_search);

free(o_array);
free(r_array);
Expand Down

0 comments on commit 6b8617b

Please sign in to comment.