Gave me an idea:
int median3c(int a, int b, int c)
{
e_type elist[7] = {a,c,a,b,b,a,c};
return elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
I am benching it now.
I guess that the 7 assignments filling the array will be expensive but
a benchmark may prove revealing.
Got another idea worth trying:
e_type median3d(e_type a, e_type b, e_type c)
{
e_type *pa = &a;
e_type *pb = &b;
e_type *pc = &c;
const e_type *elist[7] = {pa, pc, pa, pb, pb, pa, pc};
return *elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
I am benchmarking now.
/*
Using pointers offers no improvement.
*/
typedef int e_type;
e_type median3(e_type a, e_type b, e_type c)
{
return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) : ((a < c) ?
a : ((b < c) ? c : b));
}
e_type median3a(e_type a, e_type b, e_type c)
{
if (a < b) {
if (b < c)
return b; /* a b c */
if (c < a)
return a; /* c a b */
return c; /* a c b */
} else {
if (a < c)
return a; /* b a c */
if (c < b)
return b; /* c b a */
return c; /* b c a */
}
}
e_type median3b(e_type a, e_type b, e_type c)
{
switch ((a > b) + ((b > c) << 1) + ((c > a) << 2)) {
case 0:
return a;
case 1:
return c;
case 2:
return a;
case 3:
return b;
case 4:
return b;
case 5:
return a;
case 6:
default:
return c;
}
}
e_type median3c(e_type a, e_type b, e_type c)
{
e_type elist[7] = {a, c, a, b, b, a, c};
return elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
e_type median3d(e_type a, e_type b, e_type c)
{
e_type *pa = &a;
e_type *pb = &b;
e_type *pc = &c;
const e_type *elist[7] = {pa, pc, pa, pb, pb, pa, pc};
return *elist[(a > b) + ((b > c) << 1) + ((c > a) << 2)];
}
#ifdef UNIT_TEST
#include <stdio.h>
int main(void)
{
e_type i,
j,
k,
m,
m2,
m3,
m4,
m5;
for (i = 0; i < 3000; i++)
for (j = 0; j < 3000; j++)
for (k = 0; k < 3000; k++) {
m = median3(i, j, k);
m2 = median3a(i, j, k);
m3 = median3b(i, j, k);
m4 = median3c(i, j, k);
m5 = median3d(i, j, k);
#ifdef SHOW_RESULTS
printf("median of %d %d %d is %d\n", i, j, k, m3);
#endif
if (m5 != m)
printf("Disagreement (5) of %d verses %d\n", m5,
m);
if (m4 != m)
printf("Disagreement (4) of %d verses %d\n", m4,
m);
if (m3 != m)
printf("Disagreement (3) of %d verses %d\n", m3,
m);
if (m2 != m)
printf("Disagreement (2) of %d verses %d\n", m2,
m);
}
return 0;
}
#endif
/*
Profile results were:
Function Name,Exclusive Samples,Exclusive Samples %,
"median3d","48,112",25.95,
"median3c","47,707",25.73,
"median3b","40,897",22.06,
"main","27,725",14.95,
"median3a","10,774",5.81,
"median3","10,196",5.50,
*/