1 /*
2  * TestAllocSpeed
3  *
4  * Author: Lasse Collin <lasse.collin@tukaani.org>
5  *
6  * This file has been put into the public domain.
7  * You can do whatever you want with this file.
8  */
9 
10 /*
11  * Usage:
12  *   time java -jar build/jar/TestAllocSpeed.jar MODE ITERS THREADS < FILE
13  * where
14  *   MODE is "true" for compression or "false" for decompression,
15  *   ITERS is the number of iterations to done by each thread,
16  *   THREADS is the number of threads, and
17  *   FILE is the input file (preferably tiny, but at most 1 MiB).
18  *
19  * Each thread has a different random seed so in compression mode each
20  * thread will use different options in different order. This way the
21  * ArrayCache gets more diverse load.
22  *
23  * Examples:
24  *   time java -jar build/jar/TestAllocSpeed.jar true 1000 4 < README
25  *   time java -jar build/jar/TestAllocSpeed.jar false 10000 4 < foo.xz
26  */
27 
28 import java.io.*;
29 import java.util.Random;
30 import org.tukaani.xz.*;
31 
32 class TestAllocSpeed implements Runnable {
33     private static boolean compressing;
34     private static int repeats;
35     private static final byte[] testdata = new byte[1 << 20];
36     private static int testdataSize;
37     private static volatile IOException exception = null;
38 
39     private final Random rng;
40 
TestAllocSpeed(long seed)41     public TestAllocSpeed(long seed) {
42         rng = new Random(seed);
43     }
44 
compress()45     private void compress() throws IOException {
46         ByteArrayOutputStream byteStream = new ByteArrayOutputStream(
47                 testdataSize + 1024);
48         LZMA2Options options = new LZMA2Options();
49         options.setDictSize(1 << (16 + rng.nextInt(6)));
50 
51         for (int i = 0; i < repeats; ++i) {
52             XZOutputStream out = new XZOutputStream(byteStream, options);
53             out.write(testdata, 0, testdataSize);
54             out.finish();
55         }
56     }
57 
decompress()58     private void decompress() throws IOException {
59         ByteArrayInputStream byteStream = new ByteArrayInputStream(
60                 testdata, 0, testdataSize);
61         byte[] outbuf = new byte[8192];
62 
63         for (int i = 0; i < repeats; ++i) {
64             byteStream.reset();
65             XZInputStream in = new XZInputStream(byteStream);
66             while (in.read(outbuf) > 0) {}
67         }
68     }
69 
run()70     public void run() {
71         try {
72             if (compressing) {
73                 compress();
74             } else {
75                 decompress();
76             }
77         } catch (IOException e) {
78             exception = e;
79         }
80     }
81 
main(String[] args)82     public static void main(String[] args) throws Exception {
83         compressing = Boolean.parseBoolean(args[0]);
84         repeats = Integer.parseInt(args[1]);
85         final int threadCount = Integer.parseInt(args[2]);
86 
87         if (threadCount < 1 || threadCount > 64)
88             throw new Exception("Thread count must be 1-64");
89 
90         testdataSize = System.in.read(testdata);
91 
92         ArrayCache.setDefaultCache(BasicArrayCache.getInstance());
93 
94         Thread[] threads = new Thread[threadCount];
95         for (int i = 0; i < threadCount; ++i) {
96             threads[i] = new Thread(new TestAllocSpeed(i));
97             threads[i].start();
98         }
99 
100         for (int i = 0; i < threadCount; ++i)
101             threads[i].join();
102 
103         if (exception != null)
104             throw exception;
105     }
106 }
107