summaryrefslogtreecommitdiff
path: root/util/compress/libdeflate/programs/benchmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/compress/libdeflate/programs/benchmark.c')
-rw-r--r--util/compress/libdeflate/programs/benchmark.c696
1 files changed, 0 insertions, 696 deletions
diff --git a/util/compress/libdeflate/programs/benchmark.c b/util/compress/libdeflate/programs/benchmark.c
deleted file mode 100644
index 52af8dafc..000000000
--- a/util/compress/libdeflate/programs/benchmark.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * benchmark.c - a compression testing and benchmark program
- *
- * Copyright 2016 Eric Biggers
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "test_util.h"
-
-static const tchar *const optstring = T("0::1::2::3::4::5::6::7::8::9::C:D:eghs:VYZz");
-
-enum format {
- DEFLATE_FORMAT,
- ZLIB_FORMAT,
- GZIP_FORMAT,
-};
-
-struct compressor {
- int level;
- enum format format;
- const struct engine *engine;
- void *private;
-};
-
-struct decompressor {
- enum format format;
- const struct engine *engine;
- void *private;
-};
-
-struct engine {
- const tchar *name;
-
- bool (*init_compressor)(struct compressor *);
- size_t (*compress_bound)(struct compressor *, size_t);
- size_t (*compress)(struct compressor *, const void *, size_t,
- void *, size_t);
- void (*destroy_compressor)(struct compressor *);
-
- bool (*init_decompressor)(struct decompressor *);
- bool (*decompress)(struct decompressor *, const void *, size_t,
- void *, size_t);
- void (*destroy_decompressor)(struct decompressor *);
-};
-
-/******************************************************************************/
-
-static bool
-libdeflate_engine_init_compressor(struct compressor *c)
-{
- c->private = alloc_compressor(c->level);
- return c->private != NULL;
-}
-
-static size_t
-libdeflate_engine_compress_bound(struct compressor *c, size_t in_nbytes)
-{
- switch (c->format) {
- case ZLIB_FORMAT:
- return libdeflate_zlib_compress_bound(c->private, in_nbytes);
- case GZIP_FORMAT:
- return libdeflate_gzip_compress_bound(c->private, in_nbytes);
- default:
- return libdeflate_deflate_compress_bound(c->private, in_nbytes);
- }
-}
-
-static size_t
-libdeflate_engine_compress(struct compressor *c, const void *in,
- size_t in_nbytes, void *out, size_t out_nbytes_avail)
-{
- switch (c->format) {
- case ZLIB_FORMAT:
- return libdeflate_zlib_compress(c->private, in, in_nbytes,
- out, out_nbytes_avail);
- case GZIP_FORMAT:
- return libdeflate_gzip_compress(c->private, in, in_nbytes,
- out, out_nbytes_avail);
- default:
- return libdeflate_deflate_compress(c->private, in, in_nbytes,
- out, out_nbytes_avail);
- }
-}
-
-static void
-libdeflate_engine_destroy_compressor(struct compressor *c)
-{
- libdeflate_free_compressor(c->private);
-}
-
-static bool
-libdeflate_engine_init_decompressor(struct decompressor *d)
-{
- d->private = alloc_decompressor();
- return d->private != NULL;
-}
-
-static bool
-libdeflate_engine_decompress(struct decompressor *d, const void *in,
- size_t in_nbytes, void *out, size_t out_nbytes)
-{
- switch (d->format) {
- case ZLIB_FORMAT:
- return !libdeflate_zlib_decompress(d->private, in, in_nbytes,
- out, out_nbytes, NULL);
- case GZIP_FORMAT:
- return !libdeflate_gzip_decompress(d->private, in, in_nbytes,
- out, out_nbytes, NULL);
- default:
- return !libdeflate_deflate_decompress(d->private, in, in_nbytes,
- out, out_nbytes, NULL);
- }
-}
-
-static void
-libdeflate_engine_destroy_decompressor(struct decompressor *d)
-{
- libdeflate_free_decompressor(d->private);
-}
-
-static const struct engine libdeflate_engine = {
- .name = T("libdeflate"),
-
- .init_compressor = libdeflate_engine_init_compressor,
- .compress_bound = libdeflate_engine_compress_bound,
- .compress = libdeflate_engine_compress,
- .destroy_compressor = libdeflate_engine_destroy_compressor,
-
- .init_decompressor = libdeflate_engine_init_decompressor,
- .decompress = libdeflate_engine_decompress,
- .destroy_decompressor = libdeflate_engine_destroy_decompressor,
-};
-
-/******************************************************************************/
-
-static int
-get_libz_window_bits(enum format format)
-{
- const int windowBits = 15;
- switch (format) {
- case ZLIB_FORMAT:
- return windowBits;
- case GZIP_FORMAT:
- return windowBits + 16;
- default:
- return -windowBits;
- }
-}
-
-static bool
-libz_engine_init_compressor(struct compressor *c)
-{
- z_stream *z;
-
- if (c->level > 9) {
- msg("libz only supports up to compression level 9");
- return false;
- }
-
- z = xmalloc(sizeof(*z));
- if (z == NULL)
- return false;
-
- z->next_in = NULL;
- z->avail_in = 0;
- z->zalloc = NULL;
- z->zfree = NULL;
- z->opaque = NULL;
- if (deflateInit2(z, c->level, Z_DEFLATED,
- get_libz_window_bits(c->format),
- 8, Z_DEFAULT_STRATEGY) != Z_OK)
- {
- msg("unable to initialize deflater");
- free(z);
- return false;
- }
-
- c->private = z;
- return true;
-}
-
-static size_t
-libz_engine_compress_bound(struct compressor *c, size_t in_nbytes)
-{
- return deflateBound(c->private, in_nbytes);
-}
-
-static size_t
-libz_engine_compress(struct compressor *c, const void *in, size_t in_nbytes,
- void *out, size_t out_nbytes_avail)
-{
- z_stream *z = c->private;
-
- deflateReset(z);
-
- z->next_in = (void *)in;
- z->avail_in = in_nbytes;
- z->next_out = out;
- z->avail_out = out_nbytes_avail;
-
- if (deflate(z, Z_FINISH) != Z_STREAM_END)
- return 0;
-
- return out_nbytes_avail - z->avail_out;
-}
-
-static void
-libz_engine_destroy_compressor(struct compressor *c)
-{
- z_stream *z = c->private;
-
- deflateEnd(z);
- free(z);
-}
-
-static bool
-libz_engine_init_decompressor(struct decompressor *d)
-{
- z_stream *z;
-
- z = xmalloc(sizeof(*z));
- if (z == NULL)
- return false;
-
- z->next_in = NULL;
- z->avail_in = 0;
- z->zalloc = NULL;
- z->zfree = NULL;
- z->opaque = NULL;
- if (inflateInit2(z, get_libz_window_bits(d->format)) != Z_OK) {
- msg("unable to initialize inflater");
- free(z);
- return false;
- }
-
- d->private = z;
- return true;
-}
-
-static bool
-libz_engine_decompress(struct decompressor *d, const void *in, size_t in_nbytes,
- void *out, size_t out_nbytes)
-{
- z_stream *z = d->private;
-
- inflateReset(z);
-
- z->next_in = (void *)in;
- z->avail_in = in_nbytes;
- z->next_out = out;
- z->avail_out = out_nbytes;
-
- return inflate(z, Z_FINISH) == Z_STREAM_END && z->avail_out == 0;
-}
-
-static void
-libz_engine_destroy_decompressor(struct decompressor *d)
-{
- z_stream *z = d->private;
-
- inflateEnd(z);
- free(z);
-}
-
-static const struct engine libz_engine = {
- .name = T("libz"),
-
- .init_compressor = libz_engine_init_compressor,
- .compress_bound = libz_engine_compress_bound,
- .compress = libz_engine_compress,
- .destroy_compressor = libz_engine_destroy_compressor,
-
- .init_decompressor = libz_engine_init_decompressor,
- .decompress = libz_engine_decompress,
- .destroy_decompressor = libz_engine_destroy_decompressor,
-};
-
-/******************************************************************************/
-
-static const struct engine * const all_engines[] = {
- &libdeflate_engine,
- &libz_engine,
-};
-
-#define DEFAULT_ENGINE libdeflate_engine
-
-static const struct engine *
-name_to_engine(const tchar *name)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_LEN(all_engines); i++)
- if (tstrcmp(all_engines[i]->name, name) == 0)
- return all_engines[i];
- return NULL;
-}
-
-/******************************************************************************/
-
-static bool
-compressor_init(struct compressor *c, int level, enum format format,
- const struct engine *engine)
-{
- c->level = level;
- c->format = format;
- c->engine = engine;
- return engine->init_compressor(c);
-}
-
-static size_t
-compress_bound(struct compressor *c, size_t in_nbytes)
-{
- return c->engine->compress_bound(c, in_nbytes);
-}
-
-static size_t
-do_compress(struct compressor *c, const void *in, size_t in_nbytes,
- void *out, size_t out_nbytes_avail)
-{
- return c->engine->compress(c, in, in_nbytes, out, out_nbytes_avail);
-}
-
-static void
-compressor_destroy(struct compressor *c)
-{
- if (c->engine != NULL)
- c->engine->destroy_compressor(c);
-}
-
-static bool
-decompressor_init(struct decompressor *d, enum format format,
- const struct engine *engine)
-{
- d->format = format;
- d->engine = engine;
- return engine->init_decompressor(d);
-}
-
-static bool
-do_decompress(struct decompressor *d, const void *in, size_t in_nbytes,
- void *out, size_t out_nbytes)
-{
- return d->engine->decompress(d, in, in_nbytes, out, out_nbytes);
-}
-
-static void
-decompressor_destroy(struct decompressor *d)
-{
- if (d->engine != NULL)
- d->engine->destroy_decompressor(d);
-}
-
-/******************************************************************************/
-
-static void
-show_available_engines(FILE *fp)
-{
- size_t i;
-
- fprintf(fp, "Available ENGINEs are: ");
- for (i = 0; i < ARRAY_LEN(all_engines); i++) {
- fprintf(fp, "%"TS, all_engines[i]->name);
- if (i < ARRAY_LEN(all_engines) - 1)
- fprintf(fp, ", ");
- }
- fprintf(fp, ". Default is %"TS"\n", DEFAULT_ENGINE.name);
-}
-
-static void
-show_usage(FILE *fp)
-{
- fprintf(fp,
-"Usage: %"TS" [-LVL] [-C ENGINE] [-D ENGINE] [-ghVz] [-s SIZE] [FILE]...\n"
-"Benchmark DEFLATE compression and decompression on the specified FILEs.\n"
-"\n"
-"Options:\n"
-" -0 no compression\n"
-" -1 fastest (worst) compression\n"
-" -6 medium compression (default)\n"
-" -12 slowest (best) compression\n"
-" -C ENGINE compression engine\n"
-" -D ENGINE decompression engine\n"
-" -e allow chunks to be expanded (implied by -0)\n"
-" -g use gzip format instead of raw DEFLATE\n"
-" -h print this help\n"
-" -s SIZE chunk size\n"
-" -V show version and legal information\n"
-" -z use zlib format instead of raw DEFLATE\n"
-"\n", prog_invocation_name);
-
- show_available_engines(fp);
-}
-
-static void
-show_version(void)
-{
- printf(
-"libdeflate compression benchmark program v" LIBDEFLATE_VERSION_STRING "\n"
-"Copyright 2016 Eric Biggers\n"
-"\n"
-"This program is free software which may be modified and/or redistributed\n"
-"under the terms of the MIT license. There is NO WARRANTY, to the extent\n"
-"permitted by law. See the COPYING file for details.\n"
- );
-}
-
-
-/******************************************************************************/
-
-static int
-do_benchmark(struct file_stream *in, void *original_buf, void *compressed_buf,
- void *decompressed_buf, u32 chunk_size,
- bool allow_expansion, size_t compressed_buf_size,
- struct compressor *compressor,
- struct decompressor *decompressor)
-{
- u64 total_uncompressed_size = 0;
- u64 total_compressed_size = 0;
- u64 total_compress_time = 0;
- u64 total_decompress_time = 0;
- ssize_t ret;
-
- while ((ret = xread(in, original_buf, chunk_size)) > 0) {
- u32 original_size = ret;
- size_t out_nbytes_avail;
- u32 compressed_size;
- u64 start_time;
- bool ok;
-
- total_uncompressed_size += original_size;
-
- if (allow_expansion) {
- out_nbytes_avail = compress_bound(compressor,
- original_size);
- if (out_nbytes_avail > compressed_buf_size) {
- msg("%"TS": bug in compress_bound()", in->name);
- return -1;
- }
- } else {
- out_nbytes_avail = original_size - 1;
- }
-
- /* Compress the chunk of data. */
- start_time = timer_ticks();
- compressed_size = do_compress(compressor,
- original_buf,
- original_size,
- compressed_buf,
- out_nbytes_avail);
- total_compress_time += timer_ticks() - start_time;
-
- if (compressed_size) {
- /* Successfully compressed the chunk of data. */
-
- /* Decompress the data we just compressed and compare
- * the result with the original. */
- start_time = timer_ticks();
- ok = do_decompress(decompressor,
- compressed_buf, compressed_size,
- decompressed_buf, original_size);
- total_decompress_time += timer_ticks() - start_time;
-
- if (!ok) {
- msg("%"TS": failed to decompress data",
- in->name);
- return -1;
- }
-
- if (memcmp(original_buf, decompressed_buf,
- original_size) != 0)
- {
- msg("%"TS": data did not decompress to "
- "original", in->name);
- return -1;
- }
-
- total_compressed_size += compressed_size;
- } else {
- /*
- * The chunk would have compressed to more than
- * out_nbytes_avail bytes.
- */
- if (allow_expansion) {
- msg("%"TS": bug in compress_bound()", in->name);
- return -1;
- }
- total_compressed_size += original_size;
- }
- }
-
- if (ret < 0)
- return ret;
-
- if (total_uncompressed_size == 0) {
- printf("\tFile was empty.\n");
- return 0;
- }
-
- if (total_compress_time == 0)
- total_compress_time = 1;
- if (total_decompress_time == 0)
- total_decompress_time = 1;
-
- printf("\tCompressed %"PRIu64 " => %"PRIu64" bytes (%u.%03u%%)\n",
- total_uncompressed_size, total_compressed_size,
- (unsigned int)(total_compressed_size * 100 /
- total_uncompressed_size),
- (unsigned int)(total_compressed_size * 100000 /
- total_uncompressed_size % 1000));
- printf("\tCompression time: %"PRIu64" ms (%"PRIu64" MB/s)\n",
- timer_ticks_to_ms(total_compress_time),
- timer_MB_per_s(total_uncompressed_size, total_compress_time));
- printf("\tDecompression time: %"PRIu64" ms (%"PRIu64" MB/s)\n",
- timer_ticks_to_ms(total_decompress_time),
- timer_MB_per_s(total_uncompressed_size, total_decompress_time));
-
- return 0;
-}
-
-int
-tmain(int argc, tchar *argv[])
-{
- u32 chunk_size = 1048576;
- int level = 6;
- enum format format = DEFLATE_FORMAT;
- const struct engine *compress_engine = &DEFAULT_ENGINE;
- const struct engine *decompress_engine = &DEFAULT_ENGINE;
- bool allow_expansion = false;
- struct compressor compressor = { 0 };
- struct decompressor decompressor = { 0 };
- size_t compressed_buf_size;
- void *original_buf = NULL;
- void *compressed_buf = NULL;
- void *decompressed_buf = NULL;
- tchar *default_file_list[] = { NULL };
- int opt_char;
- int i;
- int ret;
-
- begin_program(argv);
-
- while ((opt_char = tgetopt(argc, argv, optstring)) != -1) {
- switch (opt_char) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- level = parse_compression_level(opt_char, toptarg);
- if (level < 0)
- return 1;
- break;
- case 'C':
- compress_engine = name_to_engine(toptarg);
- if (compress_engine == NULL) {
- msg("invalid compression engine: \"%"TS"\"", toptarg);
- show_available_engines(stderr);
- return 1;
- }
- break;
- case 'D':
- decompress_engine = name_to_engine(toptarg);
- if (decompress_engine == NULL) {
- msg("invalid decompression engine: \"%"TS"\"", toptarg);
- show_available_engines(stderr);
- return 1;
- }
- break;
- case 'e':
- allow_expansion = true;
- break;
- case 'g':
- format = GZIP_FORMAT;
- break;
- case 'h':
- show_usage(stdout);
- return 0;
- case 's':
- chunk_size = tstrtoul(toptarg, NULL, 10);
- if (chunk_size == 0) {
- msg("invalid chunk size: \"%"TS"\"", toptarg);
- return 1;
- }
- break;
- case 'V':
- show_version();
- return 0;
- case 'Y': /* deprecated, use '-C libz' instead */
- compress_engine = &libz_engine;
- break;
- case 'Z': /* deprecated, use '-D libz' instead */
- decompress_engine = &libz_engine;
- break;
- case 'z':
- format = ZLIB_FORMAT;
- break;
- default:
- show_usage(stderr);
- return 1;
- }
- }
-
- argc -= toptind;
- argv += toptind;
-
- if (level == 0)
- allow_expansion = true;
-
- ret = -1;
- if (!compressor_init(&compressor, level, format, compress_engine))
- goto out;
- if (!decompressor_init(&decompressor, format, decompress_engine))
- goto out;
-
- if (allow_expansion)
- compressed_buf_size = compress_bound(&compressor, chunk_size);
- else
- compressed_buf_size = chunk_size - 1;
-
- original_buf = xmalloc(chunk_size);
- compressed_buf = xmalloc(compressed_buf_size);
- decompressed_buf = xmalloc(chunk_size);
-
- ret = -1;
- if (original_buf == NULL || compressed_buf == NULL ||
- decompressed_buf == NULL)
- goto out;
-
- if (argc == 0) {
- argv = default_file_list;
- argc = ARRAY_LEN(default_file_list);
- } else {
- for (i = 0; i < argc; i++)
- if (argv[i][0] == '-' && argv[i][1] == '\0')
- argv[i] = NULL;
- }
-
- printf("Benchmarking %s compression:\n",
- format == DEFLATE_FORMAT ? "DEFLATE" :
- format == ZLIB_FORMAT ? "zlib" : "gzip");
- printf("\tCompression level: %d\n", level);
- printf("\tChunk size: %"PRIu32"\n", chunk_size);
- printf("\tCompression engine: %"TS"\n", compress_engine->name);
- printf("\tDecompression engine: %"TS"\n", decompress_engine->name);
-
- for (i = 0; i < argc; i++) {
- struct file_stream in;
-
- ret = xopen_for_read(argv[i], true, &in);
- if (ret != 0)
- goto out;
-
- printf("Processing %"TS"...\n", in.name);
-
- ret = do_benchmark(&in, original_buf, compressed_buf,
- decompressed_buf, chunk_size,
- allow_expansion, compressed_buf_size,
- &compressor, &decompressor);
- xclose(&in);
- if (ret != 0)
- goto out;
- }
- ret = 0;
-out:
- free(decompressed_buf);
- free(compressed_buf);
- free(original_buf);
- decompressor_destroy(&decompressor);
- compressor_destroy(&compressor);
- return -ret;
-}