Skip to content

Commit 6b8617b

Browse files
committed
Add shar's algorithm
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 <richard.yao@alumni.stonybrook.edu>
1 parent ff7c12a commit 6b8617b

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

binary_search.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
Copyright (C) 2014-2021 Igor van den Hoven ivdhoven@gmail.com
3+
Copyright (C) 2023 Zettabyte Software LLC.
34
*/
45

56
/*
@@ -523,6 +524,36 @@ int adaptive_binary_search(int *array, unsigned int array_size, int key)
523524
return -1;
524525
}
525526

527+
int shar_binary_search(int *array, unsigned int array_size, int key)
528+
{
529+
unsigned int i;
530+
531+
switch (array_size)
532+
{
533+
default:
534+
unsigned int u = sizeof (array_size) * 8 - __builtin_clz(2U*array_size-1U) - 2;
535+
unsigned int p = 1U << (u);
536+
i = (array[p] <= key) * (array_size - p);
537+
538+
++checks;
539+
540+
while (p >>= 1) {
541+
++checks;
542+
if (array[i + p] <= key)
543+
i += p;
544+
}
545+
break;
546+
case 1:
547+
i = 0;
548+
break;
549+
case 0:
550+
return -1;
551+
}
552+
553+
++checks;
554+
return (array[i] == key) ? i : -1;
555+
}
556+
526557
// benchmark
527558

528559
long long utime()
@@ -683,6 +714,7 @@ int main(int argc, char **argv)
683714
run(monobound_quaternary_search);
684715
run(monobound_interpolated_search);
685716
run(adaptive_binary_search);
717+
run(shar_binary_search);
686718

687719
// uneven distribution
688720

@@ -701,6 +733,7 @@ int main(int argc, char **argv)
701733
run(monobound_binary_search);
702734
run(monobound_interpolated_search);
703735
run(adaptive_binary_search);
736+
run(shar_binary_search);
704737

705738
// sequential access, check stability while at it
706739

@@ -726,6 +759,7 @@ int main(int argc, char **argv)
726759
run(monobound_quaternary_search);
727760
run(monobound_interpolated_search);
728761
run(adaptive_binary_search);
762+
run(shar_binary_search);
729763

730764
free(o_array);
731765
free(r_array);

0 commit comments

Comments
 (0)