|
| 1 | +/******************************************************************************* |
| 2 | + * Copyright (c) 2009 Schooner Information Technology, Inc. |
| 3 | + * All rights reserved. |
| 4 | + * |
| 5 | + * http://www.schoonerinfotech.com/ |
| 6 | + * |
| 7 | + * Redistribution and use in source and binary forms, with or without |
| 8 | + * modification, are permitted provided that the following conditions |
| 9 | + * are met: |
| 10 | + * 1. Redistributions of source code must retain the above copyright |
| 11 | + * notice, this list of conditions and the following disclaimer. |
| 12 | + * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | + * notice, this list of conditions and the following disclaimer in the |
| 14 | + * documentation and/or other materials provided with the distribution. |
| 15 | + * 3. The name of the author may not be used to endorse or promote products |
| 16 | + * derived from this software without specific prior written permission. |
| 17 | + * |
| 18 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| 19 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| 20 | + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 21 | + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 22 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 23 | + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 24 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 27 | + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | + ******************************************************************************/ |
| 29 | +package com.schooner.MemCached; |
| 30 | + |
| 31 | +import java.util.Hashtable; |
| 32 | + |
| 33 | +import com.danga.MemCached.MemCachedClient; |
| 34 | + |
| 35 | +public class MemcachedPerfTest { |
| 36 | + |
| 37 | + // store results from threads |
| 38 | + private static Hashtable<Integer, StringBuilder> threadInfo = new Hashtable<Integer, StringBuilder>(); |
| 39 | + |
| 40 | + /** |
| 41 | + * This runs through some simple tests of the MemcacheClient. |
| 42 | + * |
| 43 | + * Command line args: args[0] = number of threads to spawn args[1] = number |
| 44 | + * of runs per thread args[2] = size of object to store |
| 45 | + * |
| 46 | + * @param args |
| 47 | + * the command line arguments |
| 48 | + */ |
| 49 | + public static void main(String[] args) { |
| 50 | + |
| 51 | + String[] serverlist = { "localhost:11211", "localhost:11212" }; |
| 52 | + |
| 53 | + // initialize the pool for memcache servers |
| 54 | + SchoonerSockIOPool pool = SchoonerSockIOPool.getInstance("test"); |
| 55 | + pool.setServers(serverlist); |
| 56 | + |
| 57 | + // pool.setInitConn(5); |
| 58 | + // pool.setMinConn(5); |
| 59 | + pool.setMaxConn(50); |
| 60 | + // pool.setMaintSleep(30); |
| 61 | + |
| 62 | + pool.setNagle(false); |
| 63 | + pool.initialize(); |
| 64 | + |
| 65 | + int threads = Integer.parseInt(args[0]); |
| 66 | + int runs = Integer.parseInt(args[1]); |
| 67 | + int size = 1024 * Integer.parseInt(args[2]); // how many kilobytes |
| 68 | + |
| 69 | + // get object to store |
| 70 | + int[] obj = new int[size]; |
| 71 | + for (int i = 0; i < size; i++) { |
| 72 | + obj[i] = i; |
| 73 | + } |
| 74 | + |
| 75 | + for (int i = 0; i < threads; i++) { |
| 76 | + bench b = new bench(runs, i, obj); |
| 77 | + b.start(); |
| 78 | + } |
| 79 | + |
| 80 | + int i = 0; |
| 81 | + while (i < threads) { |
| 82 | + if (threadInfo.containsKey(new Integer(i))) { |
| 83 | + System.out.println(threadInfo.get(new Integer(i))); |
| 84 | + i++; |
| 85 | + } else { |
| 86 | + try { |
| 87 | + Thread.sleep(1000); |
| 88 | + } catch (InterruptedException e) { |
| 89 | + e.printStackTrace(); |
| 90 | + } |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + pool.shutDown(); |
| 95 | + System.exit(1); |
| 96 | + } |
| 97 | + |
| 98 | + /** |
| 99 | + * Test code per thread. |
| 100 | + */ |
| 101 | + private static class bench extends Thread { |
| 102 | + private int runs; |
| 103 | + private int threadNum; |
| 104 | + private int[] object; |
| 105 | + private int size; |
| 106 | + |
| 107 | + public bench(int runs, int threadNum, int[] object) { |
| 108 | + this.runs = runs; |
| 109 | + this.threadNum = threadNum; |
| 110 | + this.object = object; |
| 111 | + this.size = object.length; |
| 112 | + } |
| 113 | + |
| 114 | + public void run() { |
| 115 | + |
| 116 | + StringBuilder result = new StringBuilder(); |
| 117 | + |
| 118 | + // get client instance |
| 119 | + MemCachedClient mc = new MemCachedClient("test"); |
| 120 | + |
| 121 | + // time deletes |
| 122 | + long start = System.currentTimeMillis(); |
| 123 | + // for (int i = 0; i < runs; i++) { |
| 124 | + // mc.delete(keys[i]); |
| 125 | + // } |
| 126 | + long elapse = System.currentTimeMillis() - start; |
| 127 | + float avg = (float) elapse / runs; |
| 128 | + // result.append("\nthread " + threadNum + ": runs: " + runs + |
| 129 | + // " deletes of obj " + (size / 1024) |
| 130 | + // + "KB -- avg time per req " + avg + " ms (total: " + elapse + |
| 131 | + // " ms)"); |
| 132 | + |
| 133 | + // time stores |
| 134 | + start = System.currentTimeMillis(); |
| 135 | + for (int i = 0; i < runs; i++) { |
| 136 | + mc.set(getName() + " " + i, object); |
| 137 | + } |
| 138 | + elapse = System.currentTimeMillis() - start; |
| 139 | + avg = (float) elapse / runs; |
| 140 | + result.append("\nthread " + threadNum + ": runs: " + runs + " stores of obj " + (size / 1024) |
| 141 | + + "KB -- avg time per req " + avg + " ms (total: " + elapse + " ms)"); |
| 142 | + |
| 143 | + start = System.currentTimeMillis(); |
| 144 | + for (int i = 0; i < runs; i++) { |
| 145 | + mc.get(getName() + " " + i); |
| 146 | + } |
| 147 | + elapse = System.currentTimeMillis() - start; |
| 148 | + avg = (float) elapse / runs; |
| 149 | + result.append("\nthread " + threadNum + ": runs: " + runs + " gets of obj " + (size / 1024) |
| 150 | + + "KB -- avg time per req " + avg + " ms (total: " + elapse + " ms)"); |
| 151 | + |
| 152 | + threadInfo.put(new Integer(threadNum), result); |
| 153 | + } |
| 154 | + } |
| 155 | +} |
0 commit comments