View Javadoc

1   package net.sf.ehcache;
2   
3   import java.util.UUID;
4   import java.util.concurrent.Callable;
5   import java.util.concurrent.ExecutorService;
6   import java.util.concurrent.Executors;
7   import java.util.concurrent.Future;
8   
9   import org.junit.Assert;
10  import org.junit.Ignore;
11  
12  import org.junit.Test;
13  
14  import java.util.logging.Logger;
15  
16  /***
17   * @author cdennis
18   */
19  @Ignore
20  public class ChrisCachePerformanceTest {
21  
22      private static final Logger LOG = Logger.getLogger(ChrisCachePerformanceTest.class.getName());
23  
24  //    static {
25          //System.setProperty("net.sf.ehcache.use.classic.lru", "true");
26  //    }
27  
28      @Test
29      public void testSingleThreadedPut() {
30          Cache testCache = new Cache(UUID.randomUUID().toString(), 100000, false, true, 0, 0);
31          CacheManager.getInstance().addCache(testCache);
32  
33          Double time = testPut("Single-Threaded Put Test", testCache, 20);
34  
35          LOG.info("Single-Threaded Put Test, Average Time " + time + "ms/put");
36  
37          CacheManager.getInstance().removeCache(testCache.getName());
38      }
39  
40      @Test
41      public void testMultiThreadedPut() throws Exception {
42          testMultiThreadedPut(Math.max(2, Runtime.getRuntime().availableProcessors()));
43      }
44  
45      @Test
46      public void testOverThreadedPut() throws Exception {
47          testMultiThreadedPut(4 * Math.max(2, Runtime.getRuntime().availableProcessors()));
48      }
49  
50      private void testMultiThreadedPut(final int cpuCount) throws Exception {
51          final Cache testCache = new Cache(UUID.randomUUID().toString(), 100000, false, true, 0, 0);
52          CacheManager.getInstance().addCache(testCache);
53  
54          Future<Double>[] futures = new Future[cpuCount];
55          ExecutorService[] executors = new ExecutorService[cpuCount];
56  
57          for (int i = 0; i < cpuCount; i++) {
58              final int cpu = i;
59              executors[i] = Executors.newSingleThreadExecutor();
60              futures[i] = executors[i].submit(new Callable<Double>() {
61                  public Double call() {
62                      return testPut("Multi-Threaded Put Test [" + cpuCount + " Threads], Partition " + cpu, testCache, 20, cpu, cpuCount);
63                  }
64              });
65          }
66  
67          double total = 0;
68          for (Future<Double> f : futures) {
69              total += f.get().doubleValue();
70          }
71  
72          LOG.info("Multi-Threaded Put Test, Average Time For " + cpuCount + " Threads " + (total / cpuCount) + "ms/put");
73  
74          for (ExecutorService e : executors) {
75              e.shutdown();
76          }
77  
78          CacheManager.getInstance().removeCache(testCache.getName());
79      }
80  
81      @Test
82      public void testSingleThreadedPutAtThreshold() {
83          final Cache testCache = new Cache(UUID.randomUUID().toString(), 100000, false, true, 0, 0);
84          CacheManager.getInstance().addCache(testCache);
85  
86          testPut("Warming Cache For Single-Threaded Threshold Put Test", testCache, 1);
87  
88          Double time = testThresholdPut("Single-Threaded Threshold Put Test", testCache, 20);
89  
90          LOG.info("Single-Threaded Threshold Put Test, Average Time " + time + "ms/put");
91  
92          CacheManager.getInstance().removeCache(testCache.getName());
93      }
94  
95      @Test
96      public void testMultiThreadedPutAtThreshold() throws Exception {
97          testMultiThreadedPutAtThreshold(Math.max(2, Runtime.getRuntime().availableProcessors()));
98      }
99  
100     @Test
101     public void testOverThreadedPutAtThreshold() throws Exception {
102         testMultiThreadedPutAtThreshold(4 * Math.max(2, Runtime.getRuntime().availableProcessors()));
103     }
104 
105     private void testMultiThreadedPutAtThreshold(final int cpuCount) throws Exception {
106         final Cache testCache = new Cache(UUID.randomUUID().toString(), 100000, false, true, 0, 0);
107         CacheManager.getInstance().addCache(testCache);
108 
109         testPut("Warming Cache For Multi-Threaded Threshold Put Test", testCache, 1);
110 
111         Future<Double>[] futures = new Future[cpuCount];
112         ExecutorService[] executors = new ExecutorService[cpuCount];
113 
114         for (int i = 0; i < cpuCount; i++) {
115             final int cpu = i;
116             executors[i] = Executors.newSingleThreadExecutor();
117             futures[i] = executors[i].submit(new Callable<Double>() {
118                 public Double call() {
119                     return testThresholdPut("Multi-Threaded Threshold Put Test, Partition " + cpu, testCache, 20, cpu, cpuCount);
120                 }
121             });
122         }
123 
124         double total = 0;
125         for (Future<Double> f : futures) {
126             total += f.get().doubleValue();
127         }
128 
129         LOG.info("Multi-Threaded Threshold Put Test, Average Time For " + cpuCount + " Threads " + (total / cpuCount) + "ms/put");
130 
131         for (ExecutorService e : executors) {
132             e.shutdown();
133         }
134 
135         CacheManager.getInstance().removeCache(testCache.getName());
136     }
137 
138     @Test
139     public void testSingleThreadedGet() {
140         final Cache testCache = new Cache(UUID.randomUUID().toString(), 100000, false, true, 0, 0);
141         CacheManager.getInstance().addCache(testCache);
142 
143         testPut("Warming Cache For Single-Threaded Get Test", testCache, 1);
144 
145         Double time = testGet("Single-Threaded Get Test", testCache, 20);
146 
147         LOG.info("Single-Threaded Get Test, Average Time " + time + "ms/get");
148 
149         CacheManager.getInstance().removeCache(testCache.getName());
150     }
151 
152     @Test
153     public void testMultiThreadedGet() throws Exception {
154         testMultiThreadedGet(Math.max(2, Runtime.getRuntime().availableProcessors()));
155     }
156 
157     @Test
158     public void testOverThreadedGet() throws Exception {
159         testMultiThreadedGet(4 * Math.max(2, Runtime.getRuntime().availableProcessors()));
160     }
161 
162     private void testMultiThreadedGet(final int cpuCount) throws Exception {
163         final Cache testCache = new Cache(UUID.randomUUID().toString(), 100000, false, true, 0, 0);
164         CacheManager.getInstance().addCache(testCache);
165 
166         testPut("Warming Cache For Multi-Threaded Get Test", testCache, 1);
167 
168         Future<Double>[] futures = new Future[cpuCount];
169         ExecutorService[] executors = new ExecutorService[cpuCount];
170 
171         for (int i = 0; i < cpuCount; i++) {
172             final int cpu = i;
173             executors[i] = Executors.newSingleThreadExecutor();
174             futures[i] = executors[i].submit(new Callable<Double>() {
175                 public Double call() {
176                     return testGet("Multi-Threaded Get Test, Partition " + cpu, testCache, 20, cpu, cpuCount);
177                 }
178             });
179         }
180 
181         double total = 0;
182         for (Future<Double> f : futures) {
183             total += f.get().doubleValue();
184         }
185 
186         LOG.info("Multi-Threaded Get Test, Average Time For " + cpuCount + " Threads " + (total / cpuCount) + "ms/get");
187 
188         for (ExecutorService e : executors) {
189             e.shutdown();
190         }
191 
192         CacheManager.getInstance().removeCache(testCache.getName());
193 
194     }
195 
196 
197     private static Double testPut(String test, Cache cache, int cycles) {
198         return testPut(test, cache, cycles, 0, 1);
199     }
200 
201     private static Double testPut(String test, Cache cache, int cycles, int index, int partitions) {
202         int max = cache.getCacheConfiguration().getMaxElementsInMemory();
203 
204         int begin = (max / partitions) * index;
205         int finish = (max / partitions) * (index + 1);
206 
207         long totalPuts = 0;
208         long totalTime = 0;
209         for (int c = 0; c < cycles; c++) {
210             cache.removeAll();
211             System.gc();
212 
213             long start = System.currentTimeMillis();
214             for (int i = begin; i < finish; i++) {
215                 cache.put(new Element(Integer.valueOf(i), new Object()));
216             }
217             long end = System.currentTimeMillis();
218 
219             totalPuts += (finish - begin);
220             totalTime += (end - start);
221             LOG.fine(test + ": Test Cycle " + (c + 1) + ": " + (finish - begin) + " puts took " + (end - start) + "ms ["
222                     + (((double) (end - start)) / (finish - begin)) + "ms/put]\n"
223                     + "\t\tRunning Average: " + totalPuts + " puts took " + totalTime + "ms [" + (((double) totalTime) / totalPuts) + "ms/put]");
224 
225         }
226 
227         return Double.valueOf(((double) totalTime) / totalPuts);
228     }
229 
230     private static Double testThresholdPut(String test, Cache cache, int cycles) {
231         return testThresholdPut(test, cache, cycles, 0, 1);
232     }
233 
234     private static Double testThresholdPut(String test, Cache cache, int cycles, int index, int partitions) {
235         int max = cache.getCacheConfiguration().getMaxElementsInMemory();
236 
237         long totalPuts = 0;
238         long totalTime = 0;
239         for (int c = 0; c < cycles; c++) {
240             System.gc();
241 
242             int begin = ((c + 1) * max) + (max / partitions) * index;
243             int finish = ((c + 1) * max) + (max / partitions) * (index + 1);
244 
245             long start = System.currentTimeMillis();
246             for (int i = begin; i < finish; i++) {
247                 cache.put(new Element(Integer.valueOf(i), new Object()));
248             }
249             long end = System.currentTimeMillis();
250 
251             totalPuts += (finish - begin);
252             totalTime += (end - start);
253             LOG.fine(test + ": Test Cycle " + (c + 1) + ": " + (finish - begin) + " puts took " + (end - start) + "ms ["
254                     + (((double) (end - start)) / (finish - begin)) + "ms/put]\n"
255                     + "\t\tRunning Average: " + totalPuts + " puts took " + totalTime + "ms [" + (((double) totalTime) / totalPuts) + "ms/put]");
256 
257         }
258 
259         return Double.valueOf(((double) totalTime) / totalPuts);
260     }
261 
262     private static Double testGet(String test, Cache cache, int cycles) {
263         return testGet(test, cache, cycles, 0, 1);
264     }
265 
266     private static Double testGet(String test, Cache cache, int cycles, int index, int partitions) {
267         int max = cache.getCacheConfiguration().getMaxElementsInMemory();
268 
269         int begin = (max / partitions) * index;
270         int finish = (max / partitions) * (index + 1);
271 
272         long totalGets = 0;
273         long totalTime = 0;
274         for (int c = 0; c < cycles; c++) {
275             long start = System.currentTimeMillis();
276             for (int i = begin; i < finish; i++) {
277                 Assert.assertNotNull("Element @ " + i, cache.get(Integer.valueOf(i)));
278             }
279             long end = System.currentTimeMillis();
280 
281             totalGets += (finish - begin);
282             totalTime += (end - start);
283             LOG.fine(test + ": Test Cycle " + (c + 1) + ": " + (finish - begin) + " gets took " + (end - start) + "ms ["
284                     + (((double) (end - start)) / (finish - begin)) + "ms/get]\n"
285                     + "\t\tRunning Average: " + totalGets + " gets took " + totalTime + "ms [" + (((double) totalTime) / totalGets) + "ms/get]");
286         }
287 
288         return Double.valueOf(((double) totalTime) / totalGets);
289     }
290 }