[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: A little compression...
Harry Potter schreef:
On May 24, 5:02 pm, Harry Potter <maspethro...@aol.com> wrote:
It's closed source. Do I have another choice? Perhaps a general
guide on the internet for optimizing C++ code?
What helps is using a profiler to identify the hotspots in your code.
Are you sure that most time is spend in the functions below?
Maybe this will help:
//Compares a block at loc. Cur to loc. Prev in the input buffer c.In
and returns the length.
unsigned ByteRef::ChkBlock (unsigned Cur, unsigned Prev, compbuffer
&c)
{
unsigned int i, j, k;
register unsigned char* in2=c.In;
//Get max. compare len. in j
j=Cur-Prev;
k=c.InLen-Cur; if (k<j) j=k;
if (j>65) j=65; //Max. possible ref. len. =65 bytes
for (i=0; i<j && in2[Cur+i]==in2[Prev+i]; i++);
if (i<3) i=0;
return i;
}
The register keyword is unlikely to have any beneficial effect with most
compilers. Instead of using array indexes in the for loop, you might
consider using pointer arithmetic, whether you gain anything will depend
on the compiler (untested code):
unsigned ByteRef::ChkBlock (unsigned Cur, unsigned Prev, compbuffer& c)
{
//Get max. compare len. in j
unsigned int j=Cur-Prev;
unsigned in k=c.InLen-Cur; if (k<j) j=k;
if (j>65) j=65; //Max. possible ref. len. =65 bytes
const unsigned char* start = c.In + Cur;
const unsigned char* end = c.In + j;
const unsigned char* p1 = start;
const unsigned char* p2 = c.In + Prev;
for (; p1 != end && *p1 == *p2; ++p1, ++p2);
unsigned int i = p1-start;
if (i<3) i=0;
return i;
}
You could also consider comparing 32 bit values at a time, and if the
32-bit values are unequal figure out which byte is not equal. You could
also consider using SSE instructions, which can compare 16 bytes at a
time and tell you which bytes are equal. However comparing multiple
bytes at a time does make the code quite a bit more complex.
unsigned ByteRef::ScanRef (int pos, compbuffer &c)
{
int i; //Temp. variables
int j, k;
unsigned char *in=c.In, *cu=in+pos; //Just to speed access.
len=0; //Len.=0 for init. block.
if (c.InLen-pos<3||pos<1) return 0;
//Scan from current p0os.-1 to beginning of input.
for (i=pos-1;pos<=ByteRefDepth-2?i>=0:i>=pos-(ByteRefDepth-1); i--)
{
if (*(unsigned short*)(cu)==*(unsigned short*)(in+i) &&
//If word at current pos.=word at compare block ==,
(j=ChkBlock(pos,i, c))>len) { //and better than best,
len=j; loc=i; //make current best.
}
}
return len;
}
For C++ point of view I see little room for substantial performance
improvement. Playing with the optimization settings of the compiler
and/or using a more up-to-date compiler may gain some performance
improvement, but it is very unlikely to gain orders of magnitude
improvement. In my experience changing the algorithm is the most likely
way to gain a substantial (orders of magnitude) performance improvement.
Note that non of this is topical for the groups you (and I) are posting to.