[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [E-devel] Re: E CVS: proto moom



> 
> Here are my result, on a Duron 1.3Ghz:
> 
> ....
> ....
> 
> The difference of speed between the first and the second test
> (with or without the null checks) is indeed really small (2.5%).
> But the diffence between the second and the third test is really
> more important (13.2%). So I will move the procedures of Jose
> to evas, with the null checks, and use it in Etk.
> 
> Regards ;)
> Simon TRENY <MoOm>
> 

	The greater gains in the 'hsv_to_rgb' function are also
due to the elimination of some statements and variables there.
	The 'rgb_to_hsv' func doesn't gain much from simply
removing the null checks since it's already being killed by
several such conditional checks...

	Let's see if we can do better with this function :)

	Here's the current version:
void
rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
{
   float  min, max, del;

   min = MIN(r,g);  min = MIN(min,b);
   max = MAX(r,g);  max = MAX(max,b);
   del = max - min;

   *v = (max / 255);
   if ((max == 0) || (del == 0))
     {
	*s = 0; *h = 0;
	return; 
     }

   *s = (del / max);

   if (r == max)
	*h = ((g - b) / del);
   else if (g == max)
	*h = 2 + ((b - r) / del);
   else if (b == max)
	*h = 4 + ((r - g) / del);

   *h *= 60;
   if (*h < 0) *h += 360;
}

	Those MIN,MAX's have to go... But, how?

	Let's note that if a and b are non-negative integers,
then the following relations hold:

max(a,b) = a + max(0,b - a)
min(a,b) = b - max(0,b - a)

	So, if we can find a fast way to compute max(0,x)
for x an integer in some range, than we might get somewhere.
	Fortunately, if the a,b are integers in the range
[0,255], so that x = b - a is in the range [-255,255], then
we can compute max(0,x) as ((x & (~(x >> 8))) & 0xff).

	Let's also note that in the last part of the function,
we always multiply *h times 60, so lets put that into the
statements that give *h its initial values, and might as well
put the 'if (*h<0)..' check in those as well...

	If we do these things, we can rewrite the function as:

void
rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
{
   int   max, min, d = r - g;

//  set min to MIN(g,r)
   d = ((d & (~(d >> 8))) & 0xff);
   min = r - d;
//  set max to MAX(g,r)
   max = g + d;

//  set min to MIN(b,min)
   d = min - b;
   min -= ((d & (~(d >> 8))) & 0xff);

//  set max to MAX(max,b)
   d = b - max;
   max += ((d & (~(d >> 8))) & 0xff);

   d = max - min;

   *v = (max / 255.0);
   if (!(max & d))
     {
	*s = 0; *h = 0;
	return; 
     }

   *s = (d / (float)max);
   if (r == max)
     {
	*h = 60 * ((g - b) / (float)d);
	if (*h < 0) *h += 360;
	return;
     }
   if (g == max)
     {
	*h = 120 + (60 * ((b - r) / (float)d));
	if (*h < 0) *h += 360;
	return;
     }
   *h = 240 + (60 * ((r - g) / (float)d));
   if (*h < 0) *h += 360;
}

	These very simple changes will now give us roughly 20+%
gains in this function as well.


    jose.