jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From thom...@apache.org
Subject svn commit: r1081846 - /jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/Profiler.java
Date Tue, 15 Mar 2011 16:33:27 GMT
Author: thomasm
Date: Tue Mar 15 16:33:27 2011
New Revision: 1081846

URL: http://svn.apache.org/viewvc?rev=1081846&view=rev
Log:
Profiler: package summary.

Modified:
    jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/Profiler.java

Modified: jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/Profiler.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/Profiler.java?rev=1081846&r1=1081845&r2=1081846&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/Profiler.java
(original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/Profiler.java
Tue Mar 15 16:33:27 2011
@@ -20,31 +20,41 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.TreeSet;
 
 /**
  * A simple CPU profiling tool similar to java -Xrunhprof.
  */
 public class Profiler implements Runnable {
+
+    private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n");
     private static final int MAX_ELEMENTS = 1000;
 
     public int interval = 50;
     public int depth = 16;
+    public boolean paused;
 
-    private String[] ignoreLines = arraySplit("", ',', true);
-    private String[] ignoreThreads = arraySplit(
+    String[] ignoreLines = arraySplit("", ',', true);
+    String[] ignorePackages = arraySplit("java.", ',', true);
+    String[] ignoreThreads = arraySplit(
             "java.lang.Thread.dumpThreads," +
+            "java.lang.Thread.getThreads," +
             "java.net.PlainSocketImpl.socketAccept," +
             "java.net.SocketInputStream.socketRead0," +
             "java.net.SocketOutputStream.socketWrite0," +
             "java.lang.UNIXProcess.waitForProcessExit," +
             "java.lang.Object.wait," +
             "java.lang.Thread.sleep," +
-            "sun.awt.windows.WToolkit.eventLoop,"
+            "sun.awt.windows.WToolkit.eventLoop," +
+            "sun.misc.Unsafe.park," +
+            "dalvik.system.VMStack.getThreadStackTrace," +
+            "dalvik.system.NativeStart.run"
             , ',', true);
-    private volatile boolean stop;
+    volatile boolean stop;
     private HashMap<String, Integer> counts = new HashMap<String, Integer>();
+    private HashMap<String, Integer> packages = new HashMap<String, Integer>();
     private int minCount = 1;
-    private int total;
+    int total;
     private Thread thread;
     private long time;
 
@@ -87,6 +97,9 @@ public class Profiler implements Runnabl
 
     private void tick() {
         if (interval > 0) {
+            if (paused) {
+                return;
+            }
             try {
                 Thread.sleep(interval);
             } catch (Exception e) {
@@ -100,62 +113,84 @@ public class Profiler implements Runnabl
                 continue;
             }
             StackTraceElement[] dump = entry.getValue();
-            if (dump.length == 0) {
+            if (dump == null || dump.length == 0) {
                 continue;
             }
-            boolean ignoreThis = false;
-            for (String ig : ignoreThreads) {
-                if (ig.length() > 0 && dump[0].toString().startsWith(ig)) {
-                    ignoreThis = true;
-                    break;
-                }
-            }
-            if (ignoreThis) {
+            if (startsWithAny(dump[0].toString(), ignoreThreads)) {
                 continue;
             }
             StringBuilder buff = new StringBuilder();
             // simple recursive calls are ignored
             String last = null;
+            boolean packageCounts = false;
             for (int j = 0, i = 0; i < dump.length && j < depth; i++) {
                 String el = dump[i].toString();
-                ignoreThis = false;
-                for (String ig : ignoreLines) {
-                    if (ig.length() > 0 && el.startsWith(ig)) {
-                        ignoreThis = true;
-                        break;
-                    }
-                }
-                if (!ignoreThis && !el.equals(last)) {
+                if (!el.equals(last) && !startsWithAny(el, ignoreLines)) {
                     last = el;
-                    buff.append("at ").append(el).append('\n');
+                    buff.append("at ").append(el);
+                    if (!packageCounts && !startsWithAny(el, ignorePackages)) {
+                        packageCounts = true;
+                        int index = 0;
+                        for (; index < el.length(); index++) {
+                            char c = el.charAt(index);
+                            if (Character.isUpperCase(c) || c == '(') {
+                                break;
+                            }
+                        }
+                        if (index > 0 && el.charAt(index - 1) == '.') {
+                            index--;
+                        }
+                        String packageName = el.substring(0, index);
+                        increment(packages, packageName, 0);
+                        while (true) {
+                            index = packageName.lastIndexOf('.');
+                            if (index < 0) {
+                                break;
+                            }
+                            packageName = packageName.substring(0, index);
+                            increment(packages, packageName + ".*", 0);
+                        }
+                        buff.append('+');
+                    }
+                    buff.append(LINE_SEPARATOR);
                     j++;
                 }
             }
             if (buff.length() > 0) {
-                increment(buff.toString());
+                minCount = increment(counts, buff.toString().trim(), minCount);
+                total++;
+            }
+        }
+    }
+
+    private static boolean startsWithAny(String s, String[] prefixes) {
+        for (String p : prefixes) {
+            if (p.length() > 0 && s.startsWith(p)) {
+                return true;
             }
         }
+        return false;
     }
 
-    private void increment(String trace) {
-        total++;
-        Integer oldCount = counts.get(trace);
+    private static int increment(Map<String, Integer> map, String trace, int minCount)
{
+        Integer oldCount = map.get(trace);
         if (oldCount == null) {
-            counts.put(trace, 1);
+            map.put(trace, 1);
         } else {
-            counts.put(trace, oldCount + 1);
+            map.put(trace, oldCount + 1);
         }
-        if (counts.size() > MAX_ELEMENTS) {
-            for (Iterator<Map.Entry<String, Integer>> ei = counts.entrySet().iterator();
ei.hasNext();) {
+        while (map.size() > MAX_ELEMENTS) {
+            for (Iterator<Map.Entry<String, Integer>> ei = map.entrySet().iterator();
ei.hasNext();) {
                 Map.Entry<String, Integer> e = ei.next();
                 if (e.getValue() <= minCount) {
                     ei.remove();
                 }
             }
-            if (counts.size() > MAX_ELEMENTS) {
+            if (map.size() > MAX_ELEMENTS) {
                 minCount++;
             }
         }
+        return minCount;
     }
 
     /**
@@ -165,14 +200,40 @@ public class Profiler implements Runnabl
      * @return the stack traces.
      */
     public String getTop(int count) {
+        stopCollecting();
         StringBuilder buff = new StringBuilder();
-        buff.append("Profiler: top ").append(count).append(" stack trace(s) of ").append(time).
-            append(" ms\n");
+        buff.append("Profiler Results").
+            append(LINE_SEPARATOR).
+            append(LINE_SEPARATOR).
+            append("Package summary:").
+            append(LINE_SEPARATOR);
+        for (String k : new TreeSet<String>(packages.keySet())) {
+            int percent = 100 * packages.get(k) / Math.max(total, 1);
+            if (percent >= 5) {
+                if (percent < 10) {
+                    buff.append('0');
+                }
+                buff.append(percent).append("%: ").append(k).
+                    append(LINE_SEPARATOR);
+            }
+        }
+        buff.append(LINE_SEPARATOR).
+            append("Top ").append(count).append(" stack trace(s) of ").append(time).
+            append(" ms ").append(LINE_SEPARATOR);
+        if (counts.size() == 0) {
+            buff.append("(none)");
+        }
+        appendTop(buff, counts, count, total);
+        buff.append('.');
+        return buff.toString();
+    }
+
+    private static void appendTop(StringBuilder buff, HashMap<String, Integer> map,
int count, int total) {
         for (int x = 0, min = 0;;) {
             int highest = 0;
             Map.Entry<String, Integer> best = null;
-            for (Map.Entry<String, Integer> el : counts.entrySet()) {
-                if (el.getValue() > highest) {
+            for (Map.Entry<String, Integer> el : map.entrySet()) {
+                if (el.getValue() > highest || (el.getValue() == highest && el.getKey().length()
< best.getKey().length())) {
                     best = el;
                     highest = el.getValue();
                 }
@@ -180,18 +241,21 @@ public class Profiler implements Runnabl
             if (best == null) {
                 break;
             }
-            counts.remove(best.getKey());
+            map.remove(best.getKey());
             if (++x >= count) {
                 if (best.getValue() < min) {
                     break;
                 }
                 min = best.getValue();
             }
-            buff.append(best.getValue()).append('/').append(total).
-                append('\n').append(best.getKey());
+            int c = best.getValue();
+            int percent = 100 * c / Math.max(total, 1);
+            buff.append(c).append('/').append(total).append(" (").
+                append(percent).
+                append("%):").append(LINE_SEPARATOR).
+                append(best.getKey()).
+                append(LINE_SEPARATOR);
         }
-        buff.append('.');
-        return buff.toString();
     }
 
     /**
@@ -233,3 +297,4 @@ public class Profiler implements Runnabl
     }
 
 }
+



Mime
View raw message