xref: /aosp_15_r20/external/lz4/examples/bench_functions.c (revision 27162e4e17433d5aa7cb38e7b6a433a09405fc7f)
1*27162e4eSAndroid Build Coastguard Worker /*
2*27162e4eSAndroid Build Coastguard Worker  * bench_functions.c
3*27162e4eSAndroid Build Coastguard Worker  * Copyright  : Kyle Harper
4*27162e4eSAndroid Build Coastguard Worker  * License    : Follows same licensing as the lz4.c/lz4.h program at any given time.  Currently, BSD 2.
5*27162e4eSAndroid Build Coastguard Worker  * Description: A program to demonstrate the various compression functions involved in when using LZ4_compress_default().  The idea
6*27162e4eSAndroid Build Coastguard Worker  *              is to show how each step in the call stack can be used directly, if desired.  There is also some benchmarking for
7*27162e4eSAndroid Build Coastguard Worker  *              each function to demonstrate the (probably lack of) performance difference when jumping the stack.
8*27162e4eSAndroid Build Coastguard Worker  *              (If you're new to lz4, please read simple_buffer.c to understand the fundamentals)
9*27162e4eSAndroid Build Coastguard Worker  *
10*27162e4eSAndroid Build Coastguard Worker  *              The call stack (before theoretical compiler optimizations) for LZ4_compress_default is as follows:
11*27162e4eSAndroid Build Coastguard Worker  *                LZ4_compress_default
12*27162e4eSAndroid Build Coastguard Worker  *                  LZ4_compress_fast
13*27162e4eSAndroid Build Coastguard Worker  *                    LZ4_compress_fast_extState
14*27162e4eSAndroid Build Coastguard Worker  *                      LZ4_compress_generic
15*27162e4eSAndroid Build Coastguard Worker  *
16*27162e4eSAndroid Build Coastguard Worker  *              LZ4_compress_default()
17*27162e4eSAndroid Build Coastguard Worker  *                This is the recommended function for compressing data.  It will serve as the baseline for comparison.
18*27162e4eSAndroid Build Coastguard Worker  *              LZ4_compress_fast()
19*27162e4eSAndroid Build Coastguard Worker  *                Despite its name, it's not a "fast" version of compression.  It simply decides if HEAPMODE is set and either
20*27162e4eSAndroid Build Coastguard Worker  *                allocates memory on the heap for a struct or creates the struct directly on the stack.  Stack access is generally
21*27162e4eSAndroid Build Coastguard Worker  *                faster but this function itself isn't giving that advantage, it's just some logic for compile time.
22*27162e4eSAndroid Build Coastguard Worker  *              LZ4_compress_fast_extState()
23*27162e4eSAndroid Build Coastguard Worker  *                This simply accepts all the pointers and values collected thus far and adds logic to determine how
24*27162e4eSAndroid Build Coastguard Worker  *                LZ4_compress_generic should be invoked; specifically: can the source fit into a single pass as determined by
25*27162e4eSAndroid Build Coastguard Worker  *                LZ4_64Klimit.
26*27162e4eSAndroid Build Coastguard Worker  *              LZ4_compress_generic()
27*27162e4eSAndroid Build Coastguard Worker  *                As the name suggests, this is the generic function that ultimately does most of the heavy lifting.  Calling this
28*27162e4eSAndroid Build Coastguard Worker  *                directly can help avoid some test cases and branching which might be useful in some implementation-specific
29*27162e4eSAndroid Build Coastguard Worker  *                situations, but you really need to know what you're doing AND what you're asking lz4 to do!  You also need a
30*27162e4eSAndroid Build Coastguard Worker  *                wrapper function because this function isn't exposed with lz4.h.
31*27162e4eSAndroid Build Coastguard Worker  *
32*27162e4eSAndroid Build Coastguard Worker  *              The call stack for decompression functions is shallow.  There are 2 options:
33*27162e4eSAndroid Build Coastguard Worker  *                LZ4_decompress_safe  ||  LZ4_decompress_fast
34*27162e4eSAndroid Build Coastguard Worker  *                  LZ4_decompress_generic
35*27162e4eSAndroid Build Coastguard Worker  *
36*27162e4eSAndroid Build Coastguard Worker  *               LZ4_decompress_safe
37*27162e4eSAndroid Build Coastguard Worker  *                 This is the recommended function for decompressing data.  It is considered safe because the caller specifies
38*27162e4eSAndroid Build Coastguard Worker  *                 both the size of the compressed buffer to read as well as the maximum size of the output (decompressed) buffer
39*27162e4eSAndroid Build Coastguard Worker  *                 instead of just the latter.
40*27162e4eSAndroid Build Coastguard Worker  *               LZ4_decompress_fast
41*27162e4eSAndroid Build Coastguard Worker  *                 Again, despite its name it's not a "fast" version of decompression.  It simply frees the caller of sending the
42*27162e4eSAndroid Build Coastguard Worker  *                 size of the compressed buffer (it will simply be read-to-end, hence it's non-safety).
43*27162e4eSAndroid Build Coastguard Worker  *               LZ4_decompress_generic
44*27162e4eSAndroid Build Coastguard Worker  *                 This is the generic function that both of the LZ4_decompress_* functions above end up calling.  Calling this
45*27162e4eSAndroid Build Coastguard Worker  *                 directly is not advised, period.  Furthermore, it is a static inline function in lz4.c, so there isn't a symbol
46*27162e4eSAndroid Build Coastguard Worker  *                 exposed for anyone using lz4.h to utilize.
47*27162e4eSAndroid Build Coastguard Worker  *
48*27162e4eSAndroid Build Coastguard Worker  *               Special Note About Decompression:
49*27162e4eSAndroid Build Coastguard Worker  *               Using the LZ4_decompress_safe() function protects against malicious (user) input.  If you are using data from a
50*27162e4eSAndroid Build Coastguard Worker  *               trusted source, or if your program is the producer (P) as well as its consumer (C) in a PC or MPMC setup, you can
51*27162e4eSAndroid Build Coastguard Worker  *               safely use the LZ4_decompress_fast function.
52*27162e4eSAndroid Build Coastguard Worker  */
53*27162e4eSAndroid Build Coastguard Worker 
54*27162e4eSAndroid Build Coastguard Worker /* Since lz4 compiles with c99 and not gnu/std99 we need to enable POSIX linking for time.h structs and functions. */
55*27162e4eSAndroid Build Coastguard Worker #if __STDC_VERSION__ >= 199901L
56*27162e4eSAndroid Build Coastguard Worker #define _XOPEN_SOURCE 600
57*27162e4eSAndroid Build Coastguard Worker #else
58*27162e4eSAndroid Build Coastguard Worker #define _XOPEN_SOURCE 500
59*27162e4eSAndroid Build Coastguard Worker #endif
60*27162e4eSAndroid Build Coastguard Worker #define _POSIX_C_SOURCE 199309L
61*27162e4eSAndroid Build Coastguard Worker 
62*27162e4eSAndroid Build Coastguard Worker /* Includes, for Power! */
63*27162e4eSAndroid Build Coastguard Worker #define LZ4_DISABLE_DEPRECATE_WARNINGS   /* LZ4_decompress_fast */
64*27162e4eSAndroid Build Coastguard Worker #include "lz4.h"
65*27162e4eSAndroid Build Coastguard Worker #include <stdio.h>    /* for printf() */
66*27162e4eSAndroid Build Coastguard Worker #include <stdlib.h>   /* for exit() */
67*27162e4eSAndroid Build Coastguard Worker #include <string.h>   /* for atoi() memcmp() */
68*27162e4eSAndroid Build Coastguard Worker #include <stdint.h>   /* for uint_types */
69*27162e4eSAndroid Build Coastguard Worker #include <inttypes.h> /* for PRIu64 */
70*27162e4eSAndroid Build Coastguard Worker #include <time.h>     /* for clock() */
71*27162e4eSAndroid Build Coastguard Worker #include <locale.h>   /* for setlocale() */
72*27162e4eSAndroid Build Coastguard Worker #include <limits.h>   /* for INT_MAX */
73*27162e4eSAndroid Build Coastguard Worker #include <assert.h>
74*27162e4eSAndroid Build Coastguard Worker 
75*27162e4eSAndroid Build Coastguard Worker /* We need to know what one billion is for clock timing. */
76*27162e4eSAndroid Build Coastguard Worker #define BILLION 1000000000L
77*27162e4eSAndroid Build Coastguard Worker 
78*27162e4eSAndroid Build Coastguard Worker /* Create a crude set of test IDs so we can switch on them later  (Can't switch() on a char[] or char*). */
79*27162e4eSAndroid Build Coastguard Worker #define ID__LZ4_COMPRESS_DEFAULT        1
80*27162e4eSAndroid Build Coastguard Worker #define ID__LZ4_COMPRESS_FAST           2
81*27162e4eSAndroid Build Coastguard Worker #define ID__LZ4_COMPRESS_FAST_EXTSTATE  3
82*27162e4eSAndroid Build Coastguard Worker #define ID__LZ4_COMPRESS_GENERIC        4
83*27162e4eSAndroid Build Coastguard Worker #define ID__LZ4_DECOMPRESS_SAFE         5
84*27162e4eSAndroid Build Coastguard Worker #define ID__LZ4_DECOMPRESS_FAST         6
85*27162e4eSAndroid Build Coastguard Worker 
86*27162e4eSAndroid Build Coastguard Worker 
87*27162e4eSAndroid Build Coastguard Worker /*
88*27162e4eSAndroid Build Coastguard Worker  * Easy show-error-and-bail function.
89*27162e4eSAndroid Build Coastguard Worker  */
run_screaming(const char * message,const int code)90*27162e4eSAndroid Build Coastguard Worker void run_screaming(const char *message, const int code) {
91*27162e4eSAndroid Build Coastguard Worker   printf("%s \n", message);
92*27162e4eSAndroid Build Coastguard Worker   exit(code);
93*27162e4eSAndroid Build Coastguard Worker }
94*27162e4eSAndroid Build Coastguard Worker 
95*27162e4eSAndroid Build Coastguard Worker /*
96*27162e4eSAndroid Build Coastguard Worker  * Centralize the usage function to keep main cleaner.
97*27162e4eSAndroid Build Coastguard Worker  */
usage(const char * exeName,const char * message)98*27162e4eSAndroid Build Coastguard Worker void usage(const char* exeName, const char* message) {
99*27162e4eSAndroid Build Coastguard Worker   printf("Usage: %s <iterations> \n", exeName);
100*27162e4eSAndroid Build Coastguard Worker   run_screaming(message, 1);
101*27162e4eSAndroid Build Coastguard Worker   return;
102*27162e4eSAndroid Build Coastguard Worker }
103*27162e4eSAndroid Build Coastguard Worker 
104*27162e4eSAndroid Build Coastguard Worker #define CHECK(c) { if (!(c)) { run_screaming(#c, 1); } }
105*27162e4eSAndroid Build Coastguard Worker 
106*27162e4eSAndroid Build Coastguard Worker 
107*27162e4eSAndroid Build Coastguard Worker /*
108*27162e4eSAndroid Build Coastguard Worker  * Runs the benchmark for LZ4_* function based on function_id.
109*27162e4eSAndroid Build Coastguard Worker  * @return : benchmark duration, in ns
110*27162e4eSAndroid Build Coastguard Worker  */
bench(const char * known_good_dst,const int function_id,int iterations,const char * src,char * dst,const size_t src_size,const size_t max_dst_size,const size_t comp_size)111*27162e4eSAndroid Build Coastguard Worker uint64_t bench(
112*27162e4eSAndroid Build Coastguard Worker     const char *known_good_dst,
113*27162e4eSAndroid Build Coastguard Worker     const int function_id,
114*27162e4eSAndroid Build Coastguard Worker     int iterations,
115*27162e4eSAndroid Build Coastguard Worker     const char *src,
116*27162e4eSAndroid Build Coastguard Worker     char *dst,
117*27162e4eSAndroid Build Coastguard Worker     const size_t src_size,
118*27162e4eSAndroid Build Coastguard Worker     const size_t max_dst_size,
119*27162e4eSAndroid Build Coastguard Worker     const size_t comp_size
120*27162e4eSAndroid Build Coastguard Worker   ) {
121*27162e4eSAndroid Build Coastguard Worker   int rv = 0;
122*27162e4eSAndroid Build Coastguard Worker   const int warm_up = 5000;
123*27162e4eSAndroid Build Coastguard Worker   const int acceleration = 1;
124*27162e4eSAndroid Build Coastguard Worker   LZ4_stream_t state;
125*27162e4eSAndroid Build Coastguard Worker   clock_t start = clock();
126*27162e4eSAndroid Build Coastguard Worker 
127*27162e4eSAndroid Build Coastguard Worker   // Select the right function to perform the benchmark on.  We perform 5000 initial loops to warm the cache and ensure that dst
128*27162e4eSAndroid Build Coastguard Worker   // remains matching to known_good_dst between successive calls.
129*27162e4eSAndroid Build Coastguard Worker   switch(function_id) {
130*27162e4eSAndroid Build Coastguard Worker     case ID__LZ4_COMPRESS_DEFAULT:
131*27162e4eSAndroid Build Coastguard Worker       printf("Starting benchmark for function: LZ4_compress_default()\n");
132*27162e4eSAndroid Build Coastguard Worker       for(int junk=0; junk<warm_up; junk++)
133*27162e4eSAndroid Build Coastguard Worker         rv = LZ4_compress_default(src, dst, (int)src_size, (int)max_dst_size);
134*27162e4eSAndroid Build Coastguard Worker       if (rv < 1)
135*27162e4eSAndroid Build Coastguard Worker         run_screaming("Couldn't run LZ4_compress_default()... error code received is in exit code.", rv);
136*27162e4eSAndroid Build Coastguard Worker       if (memcmp(known_good_dst, dst, max_dst_size) != 0)
137*27162e4eSAndroid Build Coastguard Worker         run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
138*27162e4eSAndroid Build Coastguard Worker       start = clock();
139*27162e4eSAndroid Build Coastguard Worker       for (int i=1; i<=iterations; i++)
140*27162e4eSAndroid Build Coastguard Worker         LZ4_compress_default(src, dst, (int)src_size, (int)max_dst_size);
141*27162e4eSAndroid Build Coastguard Worker       break;
142*27162e4eSAndroid Build Coastguard Worker 
143*27162e4eSAndroid Build Coastguard Worker     case ID__LZ4_COMPRESS_FAST:
144*27162e4eSAndroid Build Coastguard Worker       printf("Starting benchmark for function: LZ4_compress_fast()\n");
145*27162e4eSAndroid Build Coastguard Worker       for(int junk=0; junk<warm_up; junk++)
146*27162e4eSAndroid Build Coastguard Worker         rv = LZ4_compress_fast(src, dst, (int)src_size, (int)max_dst_size, acceleration);
147*27162e4eSAndroid Build Coastguard Worker       if (rv < 1)
148*27162e4eSAndroid Build Coastguard Worker         run_screaming("Couldn't run LZ4_compress_fast()... error code received is in exit code.", rv);
149*27162e4eSAndroid Build Coastguard Worker       if (memcmp(known_good_dst, dst, max_dst_size) != 0)
150*27162e4eSAndroid Build Coastguard Worker         run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
151*27162e4eSAndroid Build Coastguard Worker       start = clock();
152*27162e4eSAndroid Build Coastguard Worker       for (int i=1; i<=iterations; i++)
153*27162e4eSAndroid Build Coastguard Worker         LZ4_compress_fast(src, dst, (int)src_size, (int)max_dst_size, acceleration);
154*27162e4eSAndroid Build Coastguard Worker       break;
155*27162e4eSAndroid Build Coastguard Worker 
156*27162e4eSAndroid Build Coastguard Worker     case ID__LZ4_COMPRESS_FAST_EXTSTATE:
157*27162e4eSAndroid Build Coastguard Worker       printf("Starting benchmark for function: LZ4_compress_fast_extState()\n");
158*27162e4eSAndroid Build Coastguard Worker       for(int junk=0; junk<warm_up; junk++)
159*27162e4eSAndroid Build Coastguard Worker         rv = LZ4_compress_fast_extState(&state, src, dst, (int)src_size, (int)max_dst_size, acceleration);
160*27162e4eSAndroid Build Coastguard Worker       if (rv < 1)
161*27162e4eSAndroid Build Coastguard Worker         run_screaming("Couldn't run LZ4_compress_fast_extState()... error code received is in exit code.", rv);
162*27162e4eSAndroid Build Coastguard Worker       if (memcmp(known_good_dst, dst, max_dst_size) != 0)
163*27162e4eSAndroid Build Coastguard Worker         run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
164*27162e4eSAndroid Build Coastguard Worker       start = clock();
165*27162e4eSAndroid Build Coastguard Worker       for (int i=1; i<=iterations; i++)
166*27162e4eSAndroid Build Coastguard Worker         LZ4_compress_fast_extState(&state, src, dst, (int)src_size, (int)max_dst_size, acceleration);
167*27162e4eSAndroid Build Coastguard Worker       break;
168*27162e4eSAndroid Build Coastguard Worker 
169*27162e4eSAndroid Build Coastguard Worker //    Disabled until LZ4_compress_generic() is exposed in the header.
170*27162e4eSAndroid Build Coastguard Worker //    case ID__LZ4_COMPRESS_GENERIC:
171*27162e4eSAndroid Build Coastguard Worker //      printf("Starting benchmark for function: LZ4_compress_generic()\n");
172*27162e4eSAndroid Build Coastguard Worker //      LZ4_resetStream((LZ4_stream_t*)&state);
173*27162e4eSAndroid Build Coastguard Worker //      for(int junk=0; junk<warm_up; junk++) {
174*27162e4eSAndroid Build Coastguard Worker //        LZ4_resetStream((LZ4_stream_t*)&state);
175*27162e4eSAndroid Build Coastguard Worker //        //rv = LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, notLimited, byU16, noDict, noDictIssue, acceleration);
176*27162e4eSAndroid Build Coastguard Worker //        LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, acceleration);
177*27162e4eSAndroid Build Coastguard Worker //      }
178*27162e4eSAndroid Build Coastguard Worker //      if (rv < 1)
179*27162e4eSAndroid Build Coastguard Worker //        run_screaming("Couldn't run LZ4_compress_generic()... error code received is in exit code.", rv);
180*27162e4eSAndroid Build Coastguard Worker //      if (memcmp(known_good_dst, dst, max_dst_size) != 0)
181*27162e4eSAndroid Build Coastguard Worker //        run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
182*27162e4eSAndroid Build Coastguard Worker //      for (int i=1; i<=iterations; i++) {
183*27162e4eSAndroid Build Coastguard Worker //        LZ4_resetStream((LZ4_stream_t*)&state);
184*27162e4eSAndroid Build Coastguard Worker //        //LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, notLimited, byU16, noDict, noDictIssue, acceleration);
185*27162e4eSAndroid Build Coastguard Worker //        LZ4_compress_generic_wrapper(&state, src, dst, src_size, max_dst_size, acceleration);
186*27162e4eSAndroid Build Coastguard Worker //      }
187*27162e4eSAndroid Build Coastguard Worker //      break;
188*27162e4eSAndroid Build Coastguard Worker 
189*27162e4eSAndroid Build Coastguard Worker     case ID__LZ4_DECOMPRESS_SAFE:
190*27162e4eSAndroid Build Coastguard Worker       printf("Starting benchmark for function: LZ4_decompress_safe()\n");
191*27162e4eSAndroid Build Coastguard Worker       for(int junk=0; junk<warm_up; junk++)
192*27162e4eSAndroid Build Coastguard Worker         rv = LZ4_decompress_safe(src, dst, (int)comp_size, (int)src_size);
193*27162e4eSAndroid Build Coastguard Worker       if (rv < 1)
194*27162e4eSAndroid Build Coastguard Worker         run_screaming("Couldn't run LZ4_decompress_safe()... error code received is in exit code.", rv);
195*27162e4eSAndroid Build Coastguard Worker       if (memcmp(known_good_dst, dst, src_size) != 0)
196*27162e4eSAndroid Build Coastguard Worker         run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
197*27162e4eSAndroid Build Coastguard Worker       start = clock();
198*27162e4eSAndroid Build Coastguard Worker       for (int i=1; i<=iterations; i++)
199*27162e4eSAndroid Build Coastguard Worker         LZ4_decompress_safe(src, dst, (int)comp_size, (int)src_size);
200*27162e4eSAndroid Build Coastguard Worker       break;
201*27162e4eSAndroid Build Coastguard Worker 
202*27162e4eSAndroid Build Coastguard Worker     case ID__LZ4_DECOMPRESS_FAST:
203*27162e4eSAndroid Build Coastguard Worker       printf("Starting benchmark for function: LZ4_decompress_fast()\n");
204*27162e4eSAndroid Build Coastguard Worker       for(int junk=0; junk<warm_up; junk++)
205*27162e4eSAndroid Build Coastguard Worker         rv = LZ4_decompress_fast(src, dst, (int)src_size);
206*27162e4eSAndroid Build Coastguard Worker       if (rv < 1)
207*27162e4eSAndroid Build Coastguard Worker         run_screaming("Couldn't run LZ4_decompress_fast()... error code received is in exit code.", rv);
208*27162e4eSAndroid Build Coastguard Worker       if (memcmp(known_good_dst, dst, src_size) != 0)
209*27162e4eSAndroid Build Coastguard Worker         run_screaming("According to memcmp(), the compressed dst we got doesn't match the known_good_dst... ruh roh.", 1);
210*27162e4eSAndroid Build Coastguard Worker       start = clock();
211*27162e4eSAndroid Build Coastguard Worker       for (int i=1; i<=iterations; i++)
212*27162e4eSAndroid Build Coastguard Worker         LZ4_decompress_fast(src, dst, (int)src_size);
213*27162e4eSAndroid Build Coastguard Worker       break;
214*27162e4eSAndroid Build Coastguard Worker 
215*27162e4eSAndroid Build Coastguard Worker     default:
216*27162e4eSAndroid Build Coastguard Worker       run_screaming("The test specified isn't valid.  Please check your code.", 1);
217*27162e4eSAndroid Build Coastguard Worker       break;
218*27162e4eSAndroid Build Coastguard Worker   }
219*27162e4eSAndroid Build Coastguard Worker 
220*27162e4eSAndroid Build Coastguard Worker   { clock_t end = clock();
221*27162e4eSAndroid Build Coastguard Worker 
222*27162e4eSAndroid Build Coastguard Worker     // Low resolution timer => requires more iterations to measure something
223*27162e4eSAndroid Build Coastguard Worker     if (end == start) {
224*27162e4eSAndroid Build Coastguard Worker       assert(iterations < (INT_MAX / 10));
225*27162e4eSAndroid Build Coastguard Worker       iterations *= 10;
226*27162e4eSAndroid Build Coastguard Worker       printf("not enough iterations => increase nb of iterations to %i \n", iterations);
227*27162e4eSAndroid Build Coastguard Worker       return bench(known_good_dst, function_id, iterations, src, dst, src_size, max_dst_size, comp_size);
228*27162e4eSAndroid Build Coastguard Worker     }
229*27162e4eSAndroid Build Coastguard Worker 
230*27162e4eSAndroid Build Coastguard Worker     return (uint64_t)((double)(end - start) / CLOCKS_PER_SEC * BILLION);
231*27162e4eSAndroid Build Coastguard Worker   }
232*27162e4eSAndroid Build Coastguard Worker }
233*27162e4eSAndroid Build Coastguard Worker 
234*27162e4eSAndroid Build Coastguard Worker 
235*27162e4eSAndroid Build Coastguard Worker /*
236*27162e4eSAndroid Build Coastguard Worker  * main()
237*27162e4eSAndroid Build Coastguard Worker  * We will demonstrate the use of each function for simplicity sake.  Then we will run 2 suites of benchmarking:
238*27162e4eSAndroid Build Coastguard Worker  * Test suite A)  Uses generic Lorem Ipsum text which should be generally compressible insomuch as basic human text is
239*27162e4eSAndroid Build Coastguard Worker  *                compressible for such a small src_size
240*27162e4eSAndroid Build Coastguard Worker  * Test Suite B)  For the sake of testing, see what results we get if the data is drastically easier to compress.  IF there are
241*27162e4eSAndroid Build Coastguard Worker  *                indeed losses and IF more compressible data is faster to process, this will exacerbate the findings.
242*27162e4eSAndroid Build Coastguard Worker  */
main(int argc,char ** argv)243*27162e4eSAndroid Build Coastguard Worker int main(int argc, char **argv) {
244*27162e4eSAndroid Build Coastguard Worker   // Get and verify options.  There's really only 1:  How many iterations to run.
245*27162e4eSAndroid Build Coastguard Worker   const char* exeName = argv[0];
246*27162e4eSAndroid Build Coastguard Worker   int iterations = 1000000;
247*27162e4eSAndroid Build Coastguard Worker   if (argc > 1)
248*27162e4eSAndroid Build Coastguard Worker     iterations = atoi(argv[1]);
249*27162e4eSAndroid Build Coastguard Worker   if (iterations < 1)
250*27162e4eSAndroid Build Coastguard Worker     usage(exeName, "Argument 1 (iterations) must be > 0.");
251*27162e4eSAndroid Build Coastguard Worker 
252*27162e4eSAndroid Build Coastguard Worker   // First we will create 2 sources (char *) of 2000 bytes each.  One normal text, the other highly-compressible text.
253*27162e4eSAndroid Build Coastguard Worker   const char src[]    = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed luctus purus et risus vulputate, et mollis orci ullamcorper. Nulla facilisi. Fusce in ligula sed purus varius aliquet interdum vitae justo. Proin quis diam velit. Nulla varius iaculis auctor. Cras volutpat, justo eu dictum pulvinar, elit sem porttitor metus, et imperdiet metus sapien et ante. Nullam nisi nulla, ornare eu tristique eu, dignissim vitae diam. Nulla sagittis porta libero, a accumsan felis sagittis scelerisque.  Integer laoreet eleifend congue. Etiam rhoncus leo vel dolor fermentum, quis luctus nisl iaculis. Praesent a erat sapien. Aliquam semper mi in lorem ultrices ultricies. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In feugiat risus sed enim ultrices, at sodales nulla tristique. Maecenas eget pellentesque justo, sed pellentesque lectus. Fusce sagittis sit amet elit vel varius. Donec sed ligula nec ligula vulputate rutrum sed ut lectus. Etiam congue pharetra leo vitae cursus. Morbi enim ante, porttitor ut varius vel, tincidunt quis justo. Nunc iaculis, risus id ultrices semper, metus est efficitur ligula, vel posuere risus nunc eget purus. Ut lorem turpis, condimentum at sem sed, porta aliquam turpis. In ut sapien a nulla dictum tincidunt quis sit amet lorem. Fusce at est egestas, luctus neque eu, consectetur tortor. Phasellus eleifend ultricies nulla ac lobortis.  Morbi maximus quam cursus vehicula iaculis. Maecenas cursus vel justo ut rutrum. Curabitur magna orci, dignissim eget dapibus vitae, finibus id lacus. Praesent rhoncus mattis augue vitae bibendum. Praesent porta mauris non ultrices fermentum. Quisque vulputate ipsum in sodales pulvinar. Aliquam nec mollis felis. Donec vitae augue pulvinar, congue nisl sed, pretium purus. Fusce lobortis mi ac neque scelerisque semper. Pellentesque vel est vitae magna aliquet aliquet. Nam non dolor. Nulla facilisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi ac lacinia felis metus.";
254*27162e4eSAndroid Build Coastguard Worker   const char hc_src[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
255*27162e4eSAndroid Build Coastguard Worker   // Set and derive sizes.  Since we're using strings, use strlen() + 1 for \0.
256*27162e4eSAndroid Build Coastguard Worker   const size_t src_size = strlen(src) + 1;
257*27162e4eSAndroid Build Coastguard Worker   const size_t max_dst_size = (size_t)LZ4_compressBound((int)src_size);
258*27162e4eSAndroid Build Coastguard Worker   int bytes_returned = 0;
259*27162e4eSAndroid Build Coastguard Worker   // Now build allocations for the data we'll be playing with.
260*27162e4eSAndroid Build Coastguard Worker   char *dst               = (char*)calloc(1, max_dst_size);
261*27162e4eSAndroid Build Coastguard Worker   char *known_good_dst    = (char*)calloc(1, max_dst_size);
262*27162e4eSAndroid Build Coastguard Worker   char *known_good_hc_dst = (char*)calloc(1, max_dst_size);
263*27162e4eSAndroid Build Coastguard Worker   if (dst == NULL || known_good_dst == NULL || known_good_hc_dst == NULL)
264*27162e4eSAndroid Build Coastguard Worker     run_screaming("Couldn't allocate memory for the destination buffers.  Sad :(", 1);
265*27162e4eSAndroid Build Coastguard Worker 
266*27162e4eSAndroid Build Coastguard Worker   // Create known-good buffers to verify our tests with other functions will produce the same results.
267*27162e4eSAndroid Build Coastguard Worker   bytes_returned = LZ4_compress_default(src, known_good_dst, (int)src_size, (int)max_dst_size);
268*27162e4eSAndroid Build Coastguard Worker   if (bytes_returned < 1)
269*27162e4eSAndroid Build Coastguard Worker     run_screaming("Couldn't create a known-good destination buffer for comparison... this is bad.", 1);
270*27162e4eSAndroid Build Coastguard Worker   const size_t src_comp_size = bytes_returned;
271*27162e4eSAndroid Build Coastguard Worker   bytes_returned = LZ4_compress_default(hc_src, known_good_hc_dst, (int)src_size, (int)max_dst_size);
272*27162e4eSAndroid Build Coastguard Worker   if (bytes_returned < 1)
273*27162e4eSAndroid Build Coastguard Worker     run_screaming("Couldn't create a known-good (highly compressible) destination buffer for comparison... this is bad.", 1);
274*27162e4eSAndroid Build Coastguard Worker   const size_t hc_src_comp_size = bytes_returned;
275*27162e4eSAndroid Build Coastguard Worker 
276*27162e4eSAndroid Build Coastguard Worker 
277*27162e4eSAndroid Build Coastguard Worker   /* LZ4_compress_default() */
278*27162e4eSAndroid Build Coastguard Worker   // This is the default function so we don't need to demonstrate how to use it.  See basics.c if you need more basal information.
279*27162e4eSAndroid Build Coastguard Worker 
280*27162e4eSAndroid Build Coastguard Worker   /* LZ4_compress_fast() */
281*27162e4eSAndroid Build Coastguard Worker   // Using this function is identical to LZ4_compress_default except we need to specify an "acceleration" value.  Defaults to 1.
282*27162e4eSAndroid Build Coastguard Worker   memset(dst, 0, max_dst_size);
283*27162e4eSAndroid Build Coastguard Worker   bytes_returned = LZ4_compress_fast(src, dst, (int)src_size, (int)max_dst_size, 1);
284*27162e4eSAndroid Build Coastguard Worker   if (bytes_returned < 1)
285*27162e4eSAndroid Build Coastguard Worker     run_screaming("Failed to compress src using LZ4_compress_fast.  echo $? for return code.", bytes_returned);
286*27162e4eSAndroid Build Coastguard Worker   if (memcmp(dst, known_good_dst, bytes_returned) != 0)
287*27162e4eSAndroid Build Coastguard Worker     run_screaming("According to memcmp(), the value we got in dst from LZ4_compress_fast doesn't match the known-good value.  This is bad.", 1);
288*27162e4eSAndroid Build Coastguard Worker 
289*27162e4eSAndroid Build Coastguard Worker   /* LZ4_compress_fast_extState() */
290*27162e4eSAndroid Build Coastguard Worker   // Using this function directly requires that we build an LZ4_stream_t struct ourselves.  We do NOT have to reset it ourselves.
291*27162e4eSAndroid Build Coastguard Worker   memset(dst, 0, max_dst_size);
292*27162e4eSAndroid Build Coastguard Worker   LZ4_stream_t state;
293*27162e4eSAndroid Build Coastguard Worker   bytes_returned = LZ4_compress_fast_extState(&state, src, dst, (int)src_size, (int)max_dst_size, 1);
294*27162e4eSAndroid Build Coastguard Worker   if (bytes_returned < 1)
295*27162e4eSAndroid Build Coastguard Worker     run_screaming("Failed to compress src using LZ4_compress_fast_extState.  echo $? for return code.", bytes_returned);
296*27162e4eSAndroid Build Coastguard Worker   if (memcmp(dst, known_good_dst, bytes_returned) != 0)
297*27162e4eSAndroid Build Coastguard Worker     run_screaming("According to memcmp(), the value we got in dst from LZ4_compress_fast_extState doesn't match the known-good value.  This is bad.", 1);
298*27162e4eSAndroid Build Coastguard Worker 
299*27162e4eSAndroid Build Coastguard Worker   /* LZ4_compress_generic */
300*27162e4eSAndroid Build Coastguard Worker   // When you can exactly control the inputs and options of your LZ4 needs, you can use LZ4_compress_generic and fixed (const)
301*27162e4eSAndroid Build Coastguard Worker   // values for the enum types such as dictionary and limitations.  Any other direct-use is probably a bad idea.
302*27162e4eSAndroid Build Coastguard Worker   //
303*27162e4eSAndroid Build Coastguard Worker   // That said, the LZ4_compress_generic() function is 'static inline' and does not have a prototype in lz4.h to expose a symbol
304*27162e4eSAndroid Build Coastguard Worker   // 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
305*27162e4eSAndroid Build Coastguard Worker   // do that if they feel it's worth expanding this example.
306*27162e4eSAndroid Build Coastguard Worker   //
307*27162e4eSAndroid Build Coastguard Worker   // I will, however, leave a skeleton of what would be required to use it directly:
308*27162e4eSAndroid Build Coastguard Worker   /*
309*27162e4eSAndroid Build Coastguard Worker     memset(dst, 0, max_dst_size);
310*27162e4eSAndroid Build Coastguard Worker     // LZ4_stream_t state:  is already declared above.  We can reuse it BUT we have to reset the stream ourselves between each call.
311*27162e4eSAndroid Build Coastguard Worker     LZ4_resetStream((LZ4_stream_t *)&state);
312*27162e4eSAndroid Build Coastguard Worker     // Since src size is small we know the following enums will be used:  notLimited (0), byU16 (2), noDict (0), noDictIssue (0).
313*27162e4eSAndroid Build Coastguard Worker     bytes_returned = LZ4_compress_generic(&state, src, dst, src_size, max_dst_size, notLimited, byU16, noDict, noDictIssue, 1);
314*27162e4eSAndroid Build Coastguard Worker     if (bytes_returned < 1)
315*27162e4eSAndroid Build Coastguard Worker       run_screaming("Failed to compress src using LZ4_compress_generic.  echo $? for return code.", bytes_returned);
316*27162e4eSAndroid Build Coastguard Worker     if (memcmp(dst, known_good_dst, bytes_returned) != 0)
317*27162e4eSAndroid Build Coastguard Worker       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);
318*27162e4eSAndroid Build Coastguard Worker   */
319*27162e4eSAndroid Build Coastguard Worker 
320*27162e4eSAndroid Build Coastguard Worker 
321*27162e4eSAndroid Build Coastguard Worker   /* Benchmarking */
322*27162e4eSAndroid Build Coastguard Worker   /* Now we'll run a few rudimentary benchmarks with each function to demonstrate differences in speed based on the function used.
323*27162e4eSAndroid Build Coastguard Worker    * Remember, we cannot call LZ4_compress_generic() directly (yet) so it's disabled.
324*27162e4eSAndroid Build Coastguard Worker    */
325*27162e4eSAndroid Build Coastguard Worker   // Suite A - Normal Compressibility
326*27162e4eSAndroid Build Coastguard Worker   char *dst_d = (char*)calloc(1, src_size);
327*27162e4eSAndroid Build Coastguard Worker   CHECK(dst_d!=NULL);
328*27162e4eSAndroid Build Coastguard Worker   memset(dst, 0, max_dst_size);
329*27162e4eSAndroid Build Coastguard Worker   printf("\nStarting suite A:  Normal compressible text.\n");
330*27162e4eSAndroid Build Coastguard Worker   uint64_t time_taken__default       = bench(known_good_dst, ID__LZ4_COMPRESS_DEFAULT,       iterations, src,            dst,   src_size, max_dst_size, src_comp_size);
331*27162e4eSAndroid Build Coastguard Worker   uint64_t time_taken__fast          = bench(known_good_dst, ID__LZ4_COMPRESS_FAST,          iterations, src,            dst,   src_size, max_dst_size, src_comp_size);
332*27162e4eSAndroid Build Coastguard Worker   uint64_t time_taken__fast_extstate = bench(known_good_dst, ID__LZ4_COMPRESS_FAST_EXTSTATE, iterations, src,            dst,   src_size, max_dst_size, src_comp_size);
333*27162e4eSAndroid Build Coastguard Worker   //uint64_t time_taken__generic       = bench(known_good_dst, ID__LZ4_COMPRESS_GENERIC,       iterations, src,            dst,   src_size, max_dst_size, src_comp_size);
334*27162e4eSAndroid Build Coastguard Worker   uint64_t time_taken__decomp_safe   = bench(src,            ID__LZ4_DECOMPRESS_SAFE,        iterations, known_good_dst, dst_d, src_size, max_dst_size, src_comp_size);
335*27162e4eSAndroid Build Coastguard Worker   uint64_t time_taken__decomp_fast   = bench(src,            ID__LZ4_DECOMPRESS_FAST,        iterations, known_good_dst, dst_d, src_size, max_dst_size, src_comp_size);
336*27162e4eSAndroid Build Coastguard Worker   // Suite B - Highly Compressible
337*27162e4eSAndroid Build Coastguard Worker   memset(dst, 0, max_dst_size);
338*27162e4eSAndroid Build Coastguard Worker   printf("\nStarting suite B:  Highly compressible text.\n");
339*27162e4eSAndroid Build Coastguard Worker   uint64_t time_taken_hc__default       = bench(known_good_hc_dst, ID__LZ4_COMPRESS_DEFAULT,       iterations, hc_src,            dst,   src_size, max_dst_size, hc_src_comp_size);
340*27162e4eSAndroid Build Coastguard Worker   uint64_t time_taken_hc__fast          = bench(known_good_hc_dst, ID__LZ4_COMPRESS_FAST,          iterations, hc_src,            dst,   src_size, max_dst_size, hc_src_comp_size);
341*27162e4eSAndroid Build Coastguard Worker   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, hc_src_comp_size);
342*27162e4eSAndroid Build Coastguard Worker   //uint64_t time_taken_hc__generic       = bench(known_good_hc_dst, ID__LZ4_COMPRESS_GENERIC,       iterations, hc_src,            dst,   src_size, max_dst_size, hc_src_comp_size);
343*27162e4eSAndroid Build Coastguard Worker   uint64_t time_taken_hc__decomp_safe   = bench(hc_src,            ID__LZ4_DECOMPRESS_SAFE,        iterations, known_good_hc_dst, dst_d, src_size, max_dst_size, hc_src_comp_size);
344*27162e4eSAndroid Build Coastguard Worker   uint64_t time_taken_hc__decomp_fast   = bench(hc_src,            ID__LZ4_DECOMPRESS_FAST,        iterations, known_good_hc_dst, dst_d, src_size, max_dst_size, hc_src_comp_size);
345*27162e4eSAndroid Build Coastguard Worker 
346*27162e4eSAndroid Build Coastguard Worker   // Report and leave.
347*27162e4eSAndroid Build Coastguard Worker   setlocale(LC_ALL, "");
348*27162e4eSAndroid Build Coastguard Worker   const char *format        = "|%-14s|%-30s|%'14.9f|%'16d|%'14llu|%'13.2f%%|\n";
349*27162e4eSAndroid Build Coastguard Worker   const char *header_format = "|%-14s|%-30s|%14s|%16s|%14s|%14s|\n";
350*27162e4eSAndroid Build Coastguard Worker   const char *separator     = "+--------------+------------------------------+--------------+----------------+--------------+--------------+\n";
351*27162e4eSAndroid Build Coastguard Worker   uint64_t iterllu = (uint64_t)iterations;
352*27162e4eSAndroid Build Coastguard Worker   printf("\n");
353*27162e4eSAndroid Build Coastguard Worker   printf("%s", separator);
354*27162e4eSAndroid Build Coastguard Worker   printf(header_format, "Source", "Function Benchmarked", "Total Seconds", "Iterations/sec", "ns/Iteration", "% of default");
355*27162e4eSAndroid Build Coastguard Worker   printf("%s", separator);
356*27162e4eSAndroid Build Coastguard Worker   printf(format, "Normal Text", "LZ4_compress_default()",       (double)time_taken__default       / BILLION, (int)(iterations / ((double)time_taken__default       /BILLION)), time_taken__default       / iterllu, (double)time_taken__default       * 100 / time_taken__default);
357*27162e4eSAndroid Build Coastguard Worker   printf(format, "Normal Text", "LZ4_compress_fast()",          (double)time_taken__fast          / BILLION, (int)(iterations / ((double)time_taken__fast          /BILLION)), time_taken__fast          / iterllu, (double)time_taken__fast          * 100 / time_taken__default);
358*27162e4eSAndroid Build Coastguard Worker   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 / iterllu, (double)time_taken__fast_extstate * 100 / time_taken__default);
359*27162e4eSAndroid Build Coastguard Worker   //printf(format, "Normal Text", "LZ4_compress_generic()",       (double)time_taken__generic       / BILLION, (int)(iterations / ((double)time_taken__generic       /BILLION)), (int)time_taken__generic       / iterations, (double)time_taken__generic       * 100 / time_taken__default);
360*27162e4eSAndroid Build Coastguard Worker   printf(format, "Normal Text", "LZ4_decompress_safe()",        (double)time_taken__decomp_safe   / BILLION, (int)(iterations / ((double)time_taken__decomp_safe   /BILLION)), time_taken__decomp_safe   / iterllu, (double)time_taken__decomp_safe   * 100 / time_taken__default);
361*27162e4eSAndroid Build Coastguard Worker   printf(format, "Normal Text", "LZ4_decompress_fast()",        (double)time_taken__decomp_fast   / BILLION, (int)(iterations / ((double)time_taken__decomp_fast   /BILLION)), time_taken__decomp_fast   / iterllu, (double)time_taken__decomp_fast   * 100 / time_taken__default);
362*27162e4eSAndroid Build Coastguard Worker   printf(header_format, "", "", "", "", "", "");
363*27162e4eSAndroid Build Coastguard Worker   printf(format, "Compressible", "LZ4_compress_default()",       (double)time_taken_hc__default       / BILLION, (int)(iterations / ((double)time_taken_hc__default       /BILLION)), time_taken_hc__default       / iterllu, (double)time_taken_hc__default       * 100 / time_taken_hc__default);
364*27162e4eSAndroid Build Coastguard Worker   printf(format, "Compressible", "LZ4_compress_fast()",          (double)time_taken_hc__fast          / BILLION, (int)(iterations / ((double)time_taken_hc__fast          /BILLION)), time_taken_hc__fast          / iterllu, (double)time_taken_hc__fast          * 100 / time_taken_hc__default);
365*27162e4eSAndroid Build Coastguard Worker   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 / iterllu, (double)time_taken_hc__fast_extstate * 100 / time_taken_hc__default);
366*27162e4eSAndroid Build Coastguard Worker   //printf(format, "Compressible", "LZ4_compress_generic()",       (double)time_taken_hc__generic       / BILLION, (int)(iterations / ((double)time_taken_hc__generic       /BILLION)), (int)time_taken_hc__generic       / iterations, (double)time_taken_hc__generic       * 100 / time_taken_hc__default);
367*27162e4eSAndroid Build Coastguard Worker   printf(format, "Compressible", "LZ4_decompress_safe()",        (double)time_taken_hc__decomp_safe   / BILLION, (int)(iterations / ((double)time_taken_hc__decomp_safe   /BILLION)), time_taken_hc__decomp_safe   / iterllu, (double)time_taken_hc__decomp_safe   * 100 / time_taken_hc__default);
368*27162e4eSAndroid Build Coastguard Worker   printf(format, "Compressible", "LZ4_decompress_fast()",        (double)time_taken_hc__decomp_fast   / BILLION, (int)(iterations / ((double)time_taken_hc__decomp_fast   /BILLION)), time_taken_hc__decomp_fast   / iterllu, (double)time_taken_hc__decomp_fast   * 100 / time_taken_hc__default);
369*27162e4eSAndroid Build Coastguard Worker   printf("%s", separator);
370*27162e4eSAndroid Build Coastguard Worker   printf("\n");
371*27162e4eSAndroid Build Coastguard Worker   printf("All done, ran %d iterations per test.\n", iterations);
372*27162e4eSAndroid Build Coastguard Worker   return 0;
373*27162e4eSAndroid Build Coastguard Worker }
374