-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Improve compression performance by conditionally skipping lazy evaluation #4533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5260,12 +5260,26 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, | |
| ZSTD_buffered_policy_e zbuff) | ||
| { | ||
| size_t const dictContentSize = cdict ? cdict->dictContentSize : dictSize; | ||
| #ifdef ZSTD_LAZY_SKIP_LONG_MATCHES | ||
| int compressionLevel = (params->compressionLevel == 0) ? cctx->requestedParams.compressionLevel | ||
| : params->compressionLevel; | ||
| compressionLevel = MIN(MAX(0, compressionLevel), ZSTD_maxCLevel()); | ||
| assert(compressionLevel >= 0 && compressionLevel <= ZSTD_MAX_CLEVEL); | ||
| cctx->seqStore.lazyLimit = ZSTD_compressFastLazyLimit[compressionLevel]; | ||
| #endif | ||
| #if ZSTD_TRACE | ||
| cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0; | ||
| #endif | ||
| DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog); | ||
| /* params are supposed to be fully validated at this point */ | ||
| assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); | ||
| #ifdef ZSTD_ENABLE_COMPRESS_FAST | ||
| compressionLevel = (params->compressionLevel == 0) ? cctx->requestedParams.compressionLevel | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. create a block which both starts and end |
||
| : params->compressionLevel; | ||
| compressionLevel = MIN(MAX(0, compressionLevel), ZSTD_maxCLevel()); | ||
| assert(compressionLevel >= 0 && compressionLevel <= ZSTD_MAX_CLEVEL); | ||
| cctx->seqStore.lazyLimit = ZSTD_compressFastLazyLimit[compressionLevel]; | ||
| #endif | ||
| assert(!((dict) && (cdict))); /* either dict or cdict, not both */ | ||
| if ( (cdict) | ||
| && (cdict->dictContentSize > 0) | ||
|
|
@@ -8288,7 +8302,14 @@ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, | |
| else if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL; | ||
| else row = compressionLevel; | ||
|
|
||
| #ifdef ZSTD_LAZY_SKIP_LONG_MATCHES | ||
| { ZSTD_compressionParameters cp = | ||
| ((unsigned)(compressionLevel - 6) <= 1) /* compressionLevel == 6 || compressionLevel == 7 */ | ||
| ? ZSTD_CParametersFastCompress[tableID][compressionLevel - 6] | ||
| : ZSTD_defaultCParameters[tableID][row]; | ||
| #else | ||
| { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row]; | ||
| #endif | ||
| DEBUGLOG(5, "ZSTD_getCParams_internal selected tableID: %u row: %u strat: %u", tableID, row, (U32)cp.strategy); | ||
| /* acceleration factor */ | ||
| if (compressionLevel < 0) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,38 @@ | |
| The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table reuse with a different strategy. | ||
| This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */ | ||
|
|
||
| #ifdef ZSTD_LAZY_SKIP_LONG_MATCHES | ||
| /* Lazy evaluation is performed only if the first match length | ||
| * is <= ZSTD_compressFastLazyLimit */ | ||
| #define ZSTD_COMPRESS_FAST_BASE_LAZY_LIMIT 5 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That seems way too low. In fact, in many cases, the search is targeting 5-byte matches, so all matches would trigger this condition, effectively changing |
||
|
|
||
| #define ZSTD_MAX_CLEVEL 22 | ||
| static const size_t ZSTD_compressFastLazyLimit[ZSTD_MAX_CLEVEL + 1] = { | ||
| ZSTD_COMPRESS_FAST_BASE_LAZY_LIMIT, /* base for negative levels */ | ||
| 0, /* level 1 */ | ||
| 0, /* level 2 */ | ||
| 0, /* level 3 */ | ||
| 0, /* level 4 */ | ||
| 0, /* level 5 */ | ||
| ZSTD_COMPRESS_FAST_BASE_LAZY_LIMIT, /* level 6 */ | ||
| ZSTD_COMPRESS_FAST_BASE_LAZY_LIMIT + 1, /* level 7 */ | ||
| 0, /* level 8.*/ | ||
| 0, /* level 9.*/ | ||
| 0, /* level 10.*/ | ||
| 0, /* level 11.*/ | ||
| 0, /* level 12.*/ | ||
| 0, /* level 13 */ | ||
| 0, /* level 14 */ | ||
| 0, /* level 15 */ | ||
| 0, /* level 16 */ | ||
| 0, /* level 17 */ | ||
| 0, /* level 18 */ | ||
| 0, /* level 19 */ | ||
| 0, /* level 20 */ | ||
| 0, /* level 21 */ | ||
| 0, /* level 22 */ | ||
| }; | ||
| #endif | ||
|
|
||
| /*-************************************* | ||
| * Context memory management | ||
|
|
@@ -105,6 +137,9 @@ typedef struct { | |
| BYTE* ofCode; | ||
| size_t maxNbSeq; | ||
| size_t maxNbLit; | ||
| #ifdef ZSTD_LAZY_SKIP_LONG_MATCHES | ||
| size_t lazyLimit; /* Match length limit to allow lazy evaluation */ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is unwelcome, I would prefer we avoid adding a conditional variable here. |
||
| #endif | ||
|
|
||
| /* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength | ||
| * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too disruptive, and will make maintenance of these tables more complex for future patches.