summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyleJHarper <KyleJHarper@gmail.com>2015-10-29 01:54:51 (GMT)
committerKyleJHarper <KyleJHarper@gmail.com>2015-10-29 01:54:51 (GMT)
commit0d25185671ddbd23d91b814cfd55dd2bc3d9e8d6 (patch)
treeafa53ed3f3adc68bb564a72747dc35984ef431ba
parent02be6631beae8afa7140f6eece45333e91d22e4f (diff)
downloadlz4-0d25185671ddbd23d91b814cfd55dd2bc3d9e8d6.zip
lz4-0d25185671ddbd23d91b814cfd55dd2bc3d9e8d6.tar.gz
lz4-0d25185671ddbd23d91b814cfd55dd2bc3d9e8d6.tar.bz2
Finished the two example files. Decided to avoid adding anything to lz4.c/h to expose LZ4_compress_generic().
-rw-r--r--examples/basics.c8
-rwxr-xr-xexamples/compressFunctionsbin0 -> 68555 bytes
-rw-r--r--examples/compress_functions.c117
-rw-r--r--lib/lz4.c5
-rw-r--r--lib/lz4.h7
5 files changed, 69 insertions, 68 deletions
diff --git a/examples/basics.c b/examples/basics.c
index c8c674a..7c26473 100644
--- a/examples/basics.c
+++ b/examples/basics.c
@@ -3,8 +3,8 @@
* Copyright : Kyle Harper
* License : Follows same licensing as the lz4.c/lz4.h program at any given time. Currently, BSD 2.
* Description: Example program to demonstrate the basic usage of the compress/decompress functions within lz4.c/lz4.h.
- * The functions you'll likely want are LZ4_compress_default and LZ4_compress_fast. Both of these are documented in
- * the lz4.h header file; I guess reading them.
+ * The functions you'll likely want are LZ4_compress_default and LZ4_decompress_fast. Both of these are documented in
+ * the lz4.h header file; I recommend reading them.
*/
/* Includes, for Power! */
@@ -32,7 +32,7 @@ int main(void) {
const char *src = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
// The compression function needs to know how many bytes of data we're sending. The string above has 57 characters == 57 bytes.
const int src_size = 57;
- // LZ4 provides a function that will tell you the maximum size of compressed output based on input data via LZ4_compressBound.
+ // LZ4 provides a function that will tell you the maximum size of compressed output based on input data via LZ4_compressBound().
const int max_dst_size = LZ4_compressBound(src_size);
// We will use that size for our destination boundary when allocating space.
char *compressed_data = malloc(max_dst_size);
@@ -54,7 +54,7 @@ int main(void) {
const int compressed_data_size = return_value;
compressed_data = (char *)realloc(compressed_data, compressed_data_size);
if (compressed_data == NULL)
- run_screaming("Failed to re-alloc memeory for compressed_data. Sad :(", 1);
+ run_screaming("Failed to re-alloc memory for compressed_data. Sad :(", 1);
/* Decompression */
// Now that we've successfully compressed the information from *src to *compressed_data, let's do the opposite! We'll create a
diff --git a/examples/compressFunctions b/examples/compressFunctions
new file mode 100755
index 0000000..1b86f1f
--- /dev/null
+++ b/examples/compressFunctions
Binary files differ
diff --git a/examples/compress_functions.c b/examples/compress_functions.c
index 302f03f..08913ef 100644
--- a/examples/compress_functions.c
+++ b/examples/compress_functions.c
@@ -5,6 +5,7 @@
* Description: A program to demonstrate the various compression functions involved in when using LZ4_compress_default(). The idea
* is to show how each step in the call stack can be used directly, if desired. There is also some benchmarking for
* each function to demonstrate the (probably lack of) performance difference when jumping the stack.
+ * (If you're new to lz4, please read basics.c to understand the fundamentals)
*
* The call stack (before theoretical compiler optimizations) for LZ4_compress_default is as follows:
* LZ4_compress_default
@@ -25,11 +26,11 @@
* LZ4_compress_generic()
* As the name suggests, this is the generic function that ultimately does most of the heavy lifting. Calling this
* directly can help avoid some test cases and branching which might be useful in some implementation-specific
- * situations.
- *
+ * situations, but you really need to know what you're doing AND what you're asking lz4 to do! You also need a
+ * wrapper function because this function isn't exposed with lz4.h.
*/
-/* Since lz4 compiles with c99 and not gnu/std99 we need to enable posix linking for time.h structs and functions. */
+/* Since lz4 compiles with c99 and not gnu/std99 we need to enable POSIX linking for time.h structs and functions. */
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600
#else
@@ -39,29 +40,24 @@
/* Includes, for Power! */
#include "lz4.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h> /* for atoi() */
+#include <stdio.h> /* for printf() */
+#include <stdlib.h> /* for exit() */
+#include <string.h> /* for atoi() memcmp() */
#include <stdint.h> /* for uint_types */
#include <inttypes.h> /* for PRIu64 */
#include <time.h> /* for clock_gettime() */
+#include <locale.h> /* for setlocale() */
/* We need to know what one billion is for clock timing. */
#define BILLION 1000000000L
-/* Create a crude set of test IDs so we can switch on them later (Can't switch() on a char[] or char*. */
+/* Create a crude set of test IDs so we can switch on them later (Can't switch() on a char[] or char*). */
#define ID__LZ4_COMPRESS_DEFAULT 1
#define ID__LZ4_COMPRESS_FAST 2
#define ID__LZ4_COMPRESS_FAST_EXTSTATE 3
#define ID__LZ4_COMPRESS_GENERIC 4
#define ID__LZ4_DECOMPRESS_FAST 5
-/* Copy these to be syntactically accurate to lz4.c */
-typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive;
-typedef enum { byPtr, byU32, byU16 } tableType_t;
-typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
-typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
-
/*
@@ -96,9 +92,8 @@ uint64_t bench(const char *known_good_dst, const int function_id, const int iter
const int acceleration = 1;
LZ4_stream_t state;
- // Select the right function to perform the benchmark on. For simplicity, start the timer here. We perform 5000 initial loops
- // to warm the cache and ensure that dst remains matching to known_good_dst between successive calls.
- clock_gettime(CLOCK_MONOTONIC, &start);
+ // Select the right function to perform the benchmark on. We perform 5000 initial loops to warm the cache and ensure that dst
+ // remains matching to known_good_dst between successive calls.
switch(function_id) {
case ID__LZ4_COMPRESS_DEFAULT:
printf("Starting benchmark for function: LZ4_compress_default()\n");
@@ -108,6 +103,7 @@ uint64_t bench(const char *known_good_dst, const int function_id, const int iter
run_screaming("Couldn't run LZ4_compress_default()... error code received is in exit code.", rv);
if (memcmp(known_good_dst, dst, max_dst_size) != 0)
run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
+ clock_gettime(CLOCK_MONOTONIC, &start);
for (int i=1; i<=iterations; i++)
LZ4_compress_default(src, dst, src_size, max_dst_size);
break;
@@ -120,6 +116,7 @@ uint64_t bench(const char *known_good_dst, const int function_id, const int iter
run_screaming("Couldn't run LZ4_compress_fast()... error code received is in exit code.", rv);
if (memcmp(known_good_dst, dst, max_dst_size) != 0)
run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
+ clock_gettime(CLOCK_MONOTONIC, &start);
for (int i=1; i<=iterations; i++)
LZ4_compress_fast(src, dst, src_size, max_dst_size, acceleration);
break;
@@ -132,26 +129,30 @@ uint64_t bench(const char *known_good_dst, const int function_id, const int iter
run_screaming("Couldn't run LZ4_compress_fast_extState()... error code received is in exit code.", rv);
if (memcmp(known_good_dst, dst, max_dst_size) != 0)
run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
+ clock_gettime(CLOCK_MONOTONIC, &start);
for (int i=1; i<=iterations; i++)
LZ4_compress_fast_extState(&state, src, dst, src_size, max_dst_size, acceleration);
break;
- case ID__LZ4_COMPRESS_GENERIC:
- printf("Starting benchmark for function: LZ4_compress_generic()\n");
- LZ4_resetStream((LZ4_stream_t*)&state);
- for(int junk=0; junk<warm_up; junk++) {
- LZ4_resetStream((LZ4_stream_t*)&state);
- rv = LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, notLimited, byU16, noDict, noDictIssue, 1);
- }
- if (rv < 1)
- run_screaming("Couldn't run LZ4_compress_generic()... error code received is in exit code.", rv);
- if (memcmp(known_good_dst, dst, max_dst_size) != 0)
- run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
- for (int i=1; i<=iterations; i++) {
- LZ4_resetStream((LZ4_stream_t*)&state);
- LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, notLimited, byU16, noDict, noDictIssue, 1);
- }
- break;
+// Disabled until LZ4_compress_generic() is exposed in the header.
+// case ID__LZ4_COMPRESS_GENERIC:
+// printf("Starting benchmark for function: LZ4_compress_generic()\n");
+// LZ4_resetStream((LZ4_stream_t*)&state);
+// for(int junk=0; junk<warm_up; junk++) {
+// LZ4_resetStream((LZ4_stream_t*)&state);
+// //rv = LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, notLimited, byU16, noDict, noDictIssue, acceleration);
+// LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, acceleration);
+// }
+// if (rv < 1)
+// run_screaming("Couldn't run LZ4_compress_generic()... error code received is in exit code.", rv);
+// if (memcmp(known_good_dst, dst, max_dst_size) != 0)
+// run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
+// for (int i=1; i<=iterations; i++) {
+// LZ4_resetStream((LZ4_stream_t*)&state);
+// //LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, notLimited, byU16, noDict, noDictIssue, acceleration);
+// LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, acceleration);
+// }
+// break;
case ID__LZ4_DECOMPRESS_FAST:
printf("Starting benchmark for function: LZ4_decompress_fast()\n");
@@ -161,6 +162,7 @@ uint64_t bench(const char *known_good_dst, const int function_id, const int iter
run_screaming("Couldn't run LZ4_compress_generic()... error code received is in exit code.", rv);
if (memcmp(known_good_dst, dst, src_size) != 0)
run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
+ clock_gettime(CLOCK_MONOTONIC, &start);
for (int i=1; i<=iterations; i++)
LZ4_decompress_fast(src, dst, src_size);
break;
@@ -241,19 +243,29 @@ int main(int argc, char **argv) {
/* LZ4_compress_generic */
// When you can exactly control the inputs and options of your LZ4 needs, you can use LZ4_compress_generic and fixed (const)
// values for the enum types such as dictionary and limitations. Any other direct-use is probably a bad idea.
- memset(dst, 0, max_dst_size);
- // LZ4_stream_t state: is already declared above. We can reuse it BUT we have to reset the stream ourselves between each call.
- LZ4_resetStream((LZ4_stream_t *)&state);
- // Since src size is small we know the following enums will be used: notLimited (0), byU16 (2), noDict (0), noDictIssue (0).
- // They are hard-coded into the LZ4_compress_generic_wrapper() function that THIS program provides.
- bytes_returned = LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, notLimited, byU16, noDict, noDictIssue, 1);
- if (bytes_returned < 1)
- run_screaming("Failed to compress src using LZ4_compress_generic. echo $? for return code.", bytes_returned);
- if (memcmp(dst, known_good_dst, bytes_returned) != 0)
- run_screaming("According to memcmp(), the value we got in dst from LZ4_compress_generic doesn't match the known-good value. This is bad.", 1);
-
-
- /* Now we'll run a few benchmarks with each function to demonstrate differences in speed based on the function used. */
+ //
+ // That said, the LZ4_compress_generic() function is 'static inline' and does not have a prototype in lz4.h to expose a symbol
+ // for it. In other words: we can't access it directly. I don't want to submit a PR that modifies lz4.c/h. Yann and others can
+ // do that if they feel it's worth expanding this example.
+ //
+ // I will, however, leave a skeleton of what would be required to use it directly:
+ /*
+ memset(dst, 0, max_dst_size);
+ // LZ4_stream_t state: is already declared above. We can reuse it BUT we have to reset the stream ourselves between each call.
+ LZ4_resetStream((LZ4_stream_t *)&state);
+ // Since src size is small we know the following enums will be used: notLimited (0), byU16 (2), noDict (0), noDictIssue (0).
+ bytes_returned = LZ4_compress_generic(&state, src, dst, src_size, max_dst_size, notLimited, byU16, noDict, noDictIssue, 1);
+ if (bytes_returned < 1)
+ run_screaming("Failed to compress src using LZ4_compress_generic. echo $? for return code.", bytes_returned);
+ if (memcmp(dst, known_good_dst, bytes_returned) != 0)
+ run_screaming("According to memcmp(), the value we got in dst from LZ4_compress_generic doesn't match the known-good value. This is bad.", 1);
+ */
+
+
+ /* Benchmarking */
+ /* Now we'll run a few rudimentary benchmarks with each function to demonstrate differences in speed based on the function used.
+ * Remember, we cannot call LZ4_compress_generic() directly (yet) so it's disabled.
+ */
// Suite A - Normal Compressibility
char *dst_d = calloc(1, src_size);
memset(dst, 0, max_dst_size);
@@ -261,7 +273,7 @@ int main(int argc, char **argv) {
uint64_t time_taken__default = bench(known_good_dst, ID__LZ4_COMPRESS_DEFAULT, iterations, src, dst, src_size, max_dst_size);
uint64_t time_taken__fast = bench(known_good_dst, ID__LZ4_COMPRESS_FAST, iterations, src, dst, src_size, max_dst_size);
uint64_t time_taken__fast_extstate = bench(known_good_dst, ID__LZ4_COMPRESS_FAST_EXTSTATE, iterations, src, dst, src_size, max_dst_size);
- uint64_t time_taken__generic = bench(known_good_dst, ID__LZ4_COMPRESS_GENERIC, iterations, src, dst, src_size, max_dst_size);
+ //uint64_t time_taken__generic = bench(known_good_dst, ID__LZ4_COMPRESS_GENERIC, iterations, src, dst, src_size, max_dst_size);
uint64_t time_taken__decomp = bench(src, ID__LZ4_DECOMPRESS_FAST, iterations, known_good_dst, dst_d, src_size, max_dst_size);
// Suite B - Highly Compressible
memset(dst, 0, max_dst_size);
@@ -269,13 +281,14 @@ int main(int argc, char **argv) {
uint64_t time_taken_hc__default = bench(known_good_hc_dst, ID__LZ4_COMPRESS_DEFAULT, iterations, hc_src, dst, src_size, max_dst_size);
uint64_t time_taken_hc__fast = bench(known_good_hc_dst, ID__LZ4_COMPRESS_FAST, iterations, hc_src, dst, src_size, max_dst_size);
uint64_t time_taken_hc__fast_extstate = bench(known_good_hc_dst, ID__LZ4_COMPRESS_FAST_EXTSTATE, iterations, hc_src, dst, src_size, max_dst_size);
- uint64_t time_taken_hc__generic = bench(known_good_hc_dst, ID__LZ4_COMPRESS_GENERIC, iterations, hc_src, dst, src_size, max_dst_size);
+ //uint64_t time_taken_hc__generic = bench(known_good_hc_dst, ID__LZ4_COMPRESS_GENERIC, iterations, hc_src, dst, src_size, max_dst_size);
uint64_t time_taken_hc__decomp = bench(hc_src, ID__LZ4_DECOMPRESS_FAST, iterations, known_good_hc_dst, dst_d, src_size, max_dst_size);
// Report and leave.
- const char *format = "|%-16s|%-32s|%16.9f|%16d|%16d|%13.2f%%|\n";
- const char *header_format = "|%-16s|%-32s|%16s|%16s|%16s|%14s|\n";
- const char *separator = "+----------------+--------------------------------+----------------+----------------+----------------+--------------+\n";
+ setlocale(LC_ALL, "");
+ const char *format = "|%-14s|%-30s|%'14.9f|%'16d|%'14d|%'13.2f%%|\n";
+ const char *header_format = "|%-14s|%-30s|%14s|%16s|%14s|%14s|\n";
+ const char *separator = "+--------------+------------------------------+--------------+----------------+--------------+--------------+\n";
printf("\n");
printf("%s", separator);
printf(header_format, "Source", "Function Benchmarked", "Total Seconds", "Iterations/sec", "ns/Iteration", "% of default");
@@ -283,13 +296,13 @@ int main(int argc, char **argv) {
printf(format, "Normal Text", "LZ4_compress_default()", (double)time_taken__default / BILLION, (int)(iterations / ((double)time_taken__default /BILLION)), time_taken__default / iterations, (double)time_taken__default * 100 / time_taken__default);
printf(format, "Normal Text", "LZ4_compress_fast()", (double)time_taken__fast / BILLION, (int)(iterations / ((double)time_taken__fast /BILLION)), time_taken__fast / iterations, (double)time_taken__fast * 100 / time_taken__default);
printf(format, "Normal Text", "LZ4_compress_fast_extState()", (double)time_taken__fast_extstate / BILLION, (int)(iterations / ((double)time_taken__fast_extstate /BILLION)), time_taken__fast_extstate / iterations, (double)time_taken__fast_extstate * 100 / time_taken__default);
- printf(format, "Normal Text", "LZ4_compress_generic()", (double)time_taken__generic / BILLION, (int)(iterations / ((double)time_taken__generic /BILLION)), time_taken__generic / iterations, (double)time_taken__generic * 100 / time_taken__default);
+ //printf(format, "Normal Text", "LZ4_compress_generic()", (double)time_taken__generic / BILLION, (int)(iterations / ((double)time_taken__generic /BILLION)), time_taken__generic / iterations, (double)time_taken__generic * 100 / time_taken__default);
printf(format, "Normal Text", "LZ4_decompress_fast()", (double)time_taken__decomp / BILLION, (int)(iterations / ((double)time_taken__decomp /BILLION)), time_taken__decomp / iterations, (double)time_taken__decomp * 100 / time_taken__default);
printf(header_format, "", "", "", "", "", "");
printf(format, "Compressible", "LZ4_compress_default()", (double)time_taken_hc__default / BILLION, (int)(iterations / ((double)time_taken_hc__default /BILLION)), time_taken_hc__default / iterations, (double)time_taken_hc__default * 100 / time_taken_hc__default);
printf(format, "Compressible", "LZ4_compress_fast()", (double)time_taken_hc__fast / BILLION, (int)(iterations / ((double)time_taken_hc__fast /BILLION)), time_taken_hc__fast / iterations, (double)time_taken_hc__fast * 100 / time_taken_hc__default);
printf(format, "Compressible", "LZ4_compress_fast_extState()", (double)time_taken_hc__fast_extstate / BILLION, (int)(iterations / ((double)time_taken_hc__fast_extstate /BILLION)), time_taken_hc__fast_extstate / iterations, (double)time_taken_hc__fast_extstate * 100 / time_taken_hc__default);
- printf(format, "Compressible", "LZ4_compress_generic()", (double)time_taken_hc__generic / BILLION, (int)(iterations / ((double)time_taken_hc__generic /BILLION)), time_taken_hc__generic / iterations, (double)time_taken_hc__generic * 100 / time_taken_hc__default);
+ //printf(format, "Compressible", "LZ4_compress_generic()", (double)time_taken_hc__generic / BILLION, (int)(iterations / ((double)time_taken_hc__generic /BILLION)), time_taken_hc__generic / iterations, (double)time_taken_hc__generic * 100 / time_taken_hc__default);
printf(format, "Compressible", "LZ4_decompress_fast()", (double)time_taken_hc__decomp / BILLION, (int)(iterations / ((double)time_taken_hc__decomp /BILLION)), time_taken_hc__decomp / iterations, (double)time_taken_hc__decomp * 100 / time_taken_hc__default);
printf("%s", separator);
printf("\n");
diff --git a/lib/lz4.c b/lib/lz4.c
index f59dccc..08cf6b5 100644
--- a/lib/lz4.c
+++ b/lib/lz4.c
@@ -1097,11 +1097,6 @@ int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
}
-int LZ4_compress_generic_wrapper(void* state, const char* source, char* dest, const int inputSize, const int max_dst_size,
- const int limited_output, const int table_type, const int dictionary,
- const int dictionary_issue, const int acceleration) {
- return LZ4_compress_generic(state, source, dest, inputSize, max_dst_size, limited_output, table_type, dictionary, dictionary_issue, acceleration);
-}
/*******************************
* Decompression functions
diff --git a/lib/lz4.h b/lib/lz4.h
index b019eed..3e74002 100644
--- a/lib/lz4.h
+++ b/lib/lz4.h
@@ -180,13 +180,6 @@ LZ4_decompress_safe_partial() :
*/
int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize);
-/*
- * LZ4_compress_generic_wrapper
- * The LZ4_compress_generic function is inline and isn't easily exposed. Writing this for the time being.
- */
-int LZ4_compress_generic_wrapper(void* state, const char* source, char* dest, const int inputSize, const int max_dst_size,
- const int limited_output, const int table_type, const int dictionary,
- const int dictionary_issue, const int acceleration);
/***********************************************
* Streaming Compression Functions