summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryann.collet.73@gmail.com <yann.collet.73@gmail.com@650e7d94-2a16-8b24-b05c-7c0b3f6821cd>2011-09-15 21:37:09 (GMT)
committeryann.collet.73@gmail.com <yann.collet.73@gmail.com@650e7d94-2a16-8b24-b05c-7c0b3f6821cd>2011-09-15 21:37:09 (GMT)
commite8d1e9911229a20e1ab535fc986a7edbfe550569 (patch)
tree8e168fb8adffc73845a45394b45f472726f996fa
parente154e125fc6f5b8ef55fca30f023e3bc329a524a (diff)
downloadlz4-e8d1e9911229a20e1ab535fc986a7edbfe550569.zip
lz4-e8d1e9911229a20e1ab535fc986a7edbfe550569.tar.gz
lz4-e8d1e9911229a20e1ab535fc986a7edbfe550569.tar.bz2
small compression speed improvement
git-svn-id: https://lz4.googlecode.com/svn/trunk@22 650e7d94-2a16-8b24-b05c-7c0b3f6821cd
-rw-r--r--lz4.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/lz4.c b/lz4.c
index 9a96617..a8d1629 100644
--- a/lz4.c
+++ b/lz4.c
@@ -111,7 +111,6 @@ int LZ4_compressCtx(void** ctx,
const BYTE* ip = (BYTE*) source;
const BYTE* anchor = ip;
- const BYTE* ref;
const BYTE* const iend = ip + isize;
const BYTE* const ilimit = iend - MINMATCH;
@@ -121,7 +120,7 @@ int LZ4_compressCtx(void** ctx,
int len, length;
const int skipStrength = SKIPSTRENGTH;
- U32 skipped = 1U << skipStrength;
+ U32 forwardH;
// Init
@@ -131,17 +130,34 @@ int LZ4_compressCtx(void** ctx,
*ctx = (void*) srt;
}
HashTable = srt->hashTable;
- memset(HashTable, 0, sizeof(srt->hashTable));
+ memset((void*)HashTable, 0, sizeof(srt->hashTable));
- // Main Loop
- while (ip < ilimit+1)
- {
- ref = HashTable[HASH_VALUE(ip)];
- HashTable[HASH_VALUE(ip)] = ip;
- // Min Match
- if ((ref < ip - MAX_DISTANCE) || (*(U32*)ref != *(U32*)ip)) { ip += (skipped++) >> skipStrength ; continue; }
- skipped = (1U << skipStrength) + 3;
+ // First Byte
+ HashTable[HASH_VALUE(ip)] = ip++;
+ forwardH = HASH_VALUE(ip);
+
+ // Main Loop
+ for ( ; ; )
+ {
+ int segmentSize = (1U << skipStrength) + 3;
+ const BYTE* forwardIp = ip;
+ const BYTE* ref;
+
+ // Find a match
+ do {
+ U32 h = forwardH;
+ int skipped = segmentSize++ >> skipStrength;
+ ip = forwardIp;
+ forwardIp = ip + skipped;
+
+ if (forwardIp > ilimit) { goto _last_literals; }
+
+ forwardH = HASH_VALUE(forwardIp);
+ ref = HashTable[h];
+ HashTable[h] = ip;
+
+ } while ((ref < ip - MAX_DISTANCE) || (*(U32*)ref != *(U32*)ip));
// Catch up
while ((ip>anchor) && (ref>(BYTE*)source) && (ip[-1]==ref[-1])) { ip--; ref--; }
@@ -190,15 +206,16 @@ _endCount:
// Prepare next loop
anchor = ip++;
+ forwardH = HASH_VALUE(ip);
}
+_last_literals:
// Encode Last Literals
- len = iend - anchor;
- if (len)
+ if (anchor < iend)
{
- orun=op++;
- if (len>=(int)RUN_MASK) { *orun=(RUN_MASK<<ML_BITS); len-=RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE) len; }
- else *orun = (len<<ML_BITS);
+ int lastLitRun = iend - anchor;
+ if (lastLitRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastLitRun-=RUN_MASK; for(; lastLitRun > 254 ; lastLitRun-=255) *op++ = 255; *op++ = (BYTE) lastLitRun; }
+ else *op++ = (lastLitRun<<ML_BITS);
while (anchor < iend - 3) { *(U32*)op = *(U32*)anchor; op+=4; anchor+=4; }
while (anchor < iend ) *op++ = *anchor++;
}