Files
php-memcached/tests/compression_conditions.phpt
Rasmus Lerdorf 5833590296 zstd support (#539)
This adds zstd compression support.

The current two options, zlib and fastlz is basically a choice between performance and compression ratio.
You would choose zlib if you are memory-bound and fastlz if you are cpu-bound. With zstd, you get the
performance of fastlz with the compression of zlib. And often it wins on both. See this benchmark I ran
on json files of varying sizes: https://gist.github.com/rlerdorf/788f3d0144f9c5514d8fee9477cbe787

Taking just a 40k json blob, we see that zstd at compression level 3 reduces it to 8862 bytes. Our current
zlib 1 gets worse compression at 10091 bytes and takes longer both to compress and decompress.

      C Size  ratio%     C MB/s     D MB/s   SCORE      Name            File
        8037    19.9       0.58    2130.89       0.08   zstd 22         file-39.54k-json
        8204    20.3      31.85    2381.59       0.01   zstd 10         file-39.54k-json
        8371    20.7      47.52     547.12       0.01   zlib 9          file-39.54k-json
        8477    20.9      74.84     539.83       0.01   zlib 6          file-39.54k-json
        8862    21.9     449.86    2130.89       0.01   zstd 3          file-39.54k-json
        9171    22.7     554.62    2381.59       0.01   zstd 1          file-39.54k-json
       10091    24.9     153.94     481.99       0.01   zlib 1          file-39.54k-json
       10646    26.3      43.39    8097.40       0.01   lz4 16          file-39.54k-json
       10658    26.3      72.30    8097.40       0.01   lz4 10          file-39.54k-json
       13004    32.1    1396.10    6747.83       0.01   lz4 1           file-39.54k-json
       13321    32.9     440.08    1306.03       0.01   fastlz 2        file-39.54k-json
       14807    36.6     444.91    1156.77       0.01   fastlz 1        file-39.54k-json
       15517    38.3    1190.79    4048.70       0.02   zstd -10        file-39.54k-json

The fact that decompression a dramatically faster with zstd is a win for most common memcache uses
since they tend to be read-heavy. The PR also adds a `memcache.compression_level` INI switch which
currently only applies to zstd compression. It could probably be made to also apply to zlib and fastlz.
2023-04-27 08:32:10 -07:00

126 lines
4.4 KiB
PHP

--TEST--
Memcached compression test
--SKIPIF--
<?php if (!extension_loaded("memcached")) print "skip"; ?>
--FILE--
<?php
include dirname (__FILE__) . '/config.inc';
$m = memc_get_instance ();
$short_data = "abcdefg";
$data = file_get_contents(dirname(__FILE__) . '/testdata.res');
set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
echo "$errstr\n";
return true;
}, E_WARNING);
function get_compression($name) {
switch (strtolower($name)) {
case 'zlib':
return Memcached::COMPRESSION_ZLIB;
case 'fastlz':
return Memcached::COMPRESSION_FASTLZ;
case 'zstd':
return Memcached::COMPRESSION_ZSTD;
default:
echo "Strange compression type: $name\n";
return 0;
}
}
function fetch_with_compression($m, $key, $value, $set_compression = '', $factor = 1.3, $threshold = 2000) {
ini_set("memcached.compression_factor", $factor);
ini_set("memcached.compression_threshold", $threshold);
$len=strlen($value);
echo "len=[$len] set=[$set_compression] factor=[$factor] threshold=[$threshold]\n";
if (!$set_compression) {
$m->setOption(Memcached::OPT_COMPRESSION, false);
} else {
$m->setOption(Memcached::OPT_COMPRESSION, true);
$m->setOption(Memcached::OPT_COMPRESSION_TYPE, get_compression($set_compression));
}
$m->set($key, $value, 1800);
$value_back = $m->get($key);
var_dump($value === $value_back);
}
fetch_with_compression($m, 'hello01', $data, 'zlib', 1.3, 4);
fetch_with_compression($m, 'hello02', $data, 'fastlz', 1.3, 4);
fetch_with_compression($m, 'hello03', $data, '', 1.3, 4);
fetch_with_compression($m, 'hello04', $short_data, 'zlib', 1.3, 4);
fetch_with_compression($m, 'hello05', $short_data, 'fastlz', 1.3, 4);
fetch_with_compression($m, 'hello06', $short_data, '', 1.3, 4);
fetch_with_compression($m, 'hello11', $data, 'zlib', 0.3, 4);
fetch_with_compression($m, 'hello12', $data, 'fastlz', 0.3, 4);
fetch_with_compression($m, 'hello13', $data, '', 0.3, 4);
fetch_with_compression($m, 'hello14', $short_data, 'zlib', 0.3, 4);
fetch_with_compression($m, 'hello15', $short_data, 'fastlz', 0.3, 4);
fetch_with_compression($m, 'hello16', $short_data, '', 0.3, 4);
fetch_with_compression($m, 'hello21', $data, 'zlib', 1.3, 2000);
fetch_with_compression($m, 'hello22', $data, 'fastlz', 1.3, 2000);
fetch_with_compression($m, 'hello23', $data, '', 1.3, 2000);
fetch_with_compression($m, 'hello24', $short_data, 'zlib', 1.3, 2000);
fetch_with_compression($m, 'hello25', $short_data, 'fastlz', 1.3, 2000);
fetch_with_compression($m, 'hello26', $short_data, '', 1.3, 2000);
fetch_with_compression($m, 'hello31', $data, 'zlib', 0.3, 2000);
fetch_with_compression($m, 'hello32', $data, 'fastlz', 0.3, 2000);
fetch_with_compression($m, 'hello33', $data, '', 0.3, 2000);
fetch_with_compression($m, 'hello34', $short_data, 'zlib', 0.3, 2000);
fetch_with_compression($m, 'hello35', $short_data, 'fastlz', 0.3, 2000);
fetch_with_compression($m, 'hello36', $short_data, '', 0.3, 2000);
?>
--EXPECT--
len=[4877] set=[zlib] factor=[1.3] threshold=[4]
bool(true)
len=[4877] set=[fastlz] factor=[1.3] threshold=[4]
bool(true)
len=[4877] set=[] factor=[1.3] threshold=[4]
bool(true)
len=[7] set=[zlib] factor=[1.3] threshold=[4]
bool(true)
len=[7] set=[fastlz] factor=[1.3] threshold=[4]
bool(true)
len=[7] set=[] factor=[1.3] threshold=[4]
bool(true)
len=[4877] set=[zlib] factor=[0.3] threshold=[4]
bool(true)
len=[4877] set=[fastlz] factor=[0.3] threshold=[4]
bool(true)
len=[4877] set=[] factor=[0.3] threshold=[4]
bool(true)
len=[7] set=[zlib] factor=[0.3] threshold=[4]
bool(true)
len=[7] set=[fastlz] factor=[0.3] threshold=[4]
bool(true)
len=[7] set=[] factor=[0.3] threshold=[4]
bool(true)
len=[4877] set=[zlib] factor=[1.3] threshold=[2000]
bool(true)
len=[4877] set=[fastlz] factor=[1.3] threshold=[2000]
bool(true)
len=[4877] set=[] factor=[1.3] threshold=[2000]
bool(true)
len=[7] set=[zlib] factor=[1.3] threshold=[2000]
bool(true)
len=[7] set=[fastlz] factor=[1.3] threshold=[2000]
bool(true)
len=[7] set=[] factor=[1.3] threshold=[2000]
bool(true)
len=[4877] set=[zlib] factor=[0.3] threshold=[2000]
bool(true)
len=[4877] set=[fastlz] factor=[0.3] threshold=[2000]
bool(true)
len=[4877] set=[] factor=[0.3] threshold=[2000]
bool(true)
len=[7] set=[zlib] factor=[0.3] threshold=[2000]
bool(true)
len=[7] set=[fastlz] factor=[0.3] threshold=[2000]
bool(true)
len=[7] set=[] factor=[0.3] threshold=[2000]
bool(true)