1 23 24 25 package com.sun.jdo.api.persistence.enhancer.util; 26 27 import java.util.HashMap ; 28 import java.util.ArrayList ; 29 import java.util.Arrays ; 30 import java.util.Comparator ; 31 32 import java.text.DecimalFormat ; 33 34 import java.io.PrintWriter ; 35 36 37 40 public final class Timer { 42 static private class MethodDescriptor { 44 final String name; 45 int instantiations; 46 int calls; 47 long self; 48 long total; 49 50 MethodDescriptor(String name) { 51 this.name = name; 52 } 53 } 54 55 static private class MethodCall { 57 final MethodDescriptor method; 58 final String message; 59 long self; 60 long total; 61 62 MethodCall(MethodDescriptor method, 63 String message, 64 long self, 65 long total) { 66 this.method = method; 67 this.message = message; 68 this.self = self; 69 this.total = total; 70 } 71 } 72 73 PrintWriter out = new PrintWriter (System.out, true); 75 76 HashMap methods = new HashMap (); 78 79 private final ArrayList calls = new ArrayList (16); 81 82 public Timer() 83 { 84 this.out = out; 85 } 86 87 public Timer(PrintWriter out) 88 { 89 this.out = out; 90 } 91 92 public final synchronized void push(String name) { 93 push(name, name); 94 } 95 96 public final synchronized void push(String name, String message) { 97 final long now = System.currentTimeMillis(); 99 100 MethodDescriptor current = (MethodDescriptor)methods.get(name); 102 if (current == null) { 103 current = new MethodDescriptor(name); 104 methods.put(name, current); 105 } 106 107 current.calls++; 109 current.instantiations++; 110 111 calls.add(new MethodCall(current, message, now, now)); 113 } 114 115 public final synchronized void pop() 116 { 117 final long now = System.currentTimeMillis(); 119 120 final MethodCall call = (MethodCall)calls.remove(calls.size()-1); 122 123 final long currentSelf = now - call.self; 125 final long currentTotal = now - call.total; 126 127 if (calls.size() > 0) { 129 final MethodCall previous = (MethodCall)calls.get(calls.size()-1); 130 previous.self += currentTotal; 131 } 132 133 final MethodDescriptor current = call.method; 135 current.self += currentSelf; 136 if (--current.instantiations == 0) { 137 current.total += currentTotal; 138 } 139 140 if (false) { 141 out.println("Timer (n,g): " + call.message + " : (" 142 + currentSelf + ", " + currentTotal + ")"); 143 } 144 } 145 146 static private final String pad(String s, int i) 147 { 148 StringBuffer b = new StringBuffer (); 149 for (i -= s.length(); i > 0; i--) 150 b.append((char)' '); 151 b.append(s); 152 return b.toString(); 153 } 154 155 public final synchronized void print() 156 { 157 out.println("Timer : printing accumulated times ..."); 158 final Object [] calls = methods.values().toArray(); 159 160 Arrays.sort(calls, 161 new Comparator () { 162 public int compare(Object o1, 163 Object o2) { 164 return (int)(((MethodDescriptor)o2).total 165 - ((MethodDescriptor)o1).total); 166 } 167 public boolean equals(Object obj) { 168 return (compare(this, obj) == 0); 169 } 170 }); 171 172 out.println("Timer : total s self s #calls name"); 173 DecimalFormat nf = new DecimalFormat (); 174 nf.setMaximumFractionDigits(2); 175 nf.setMinimumFractionDigits(2); 176 for (int i = 0; i < calls.length; i++) { 179 final MethodDescriptor current = (MethodDescriptor)calls[i]; 180 181 out.println("Timer : " 182 + pad(nf.format(current.total / 1000.0), 8) + " " 183 + pad(nf.format(current.self / 1000.0), 8) + " " 184 + pad(String.valueOf(current.calls), 6) + " " 185 + current.name); 186 } 187 } 188 } 189 | Popular Tags |