1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Manual profiler for focused thread-specific profiling.

This commit is contained in:
Sergey Prigogin 2009-10-31 22:39:04 +00:00
parent 15a3ca473a
commit 388ee55b6e

View file

@ -0,0 +1,168 @@
/*******************************************************************************
* Copyright (c) 2009 Google, Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Manual profiler for focused thread-specific profiling.
* <p>
* Usage example:
* <pre>
* Profiler.activate();
* // Code to profile
* if (starsAlign) {
* Profiler.printStats();
* }
* Profiler.deactivate();
*
* void someMethod() {
* try {
* Profiler.startTimer("MyClass.someMethod");
* // Code to get timing for.
* } finally {
* Profiler.stopTimer("MyClass.someMethod");
* }
* }
*
* void someOtherMethod() {
* ...
* Profiler.incrementCounter("Interesting thing happened");
* ...
* }
* </pre>
*/
public class Profiler {
private static class Timer {
long elapsedTime; // In nanoseconds
long counter;
long startTime; // Time in nanoseconds when the timer was started.
int recursionDepth;
final long getElapsedTime() {
return elapsedTime;
}
final long getCounter() {
return counter;
}
final void recordEntry() {
if (recursionDepth++ == 0) {
startTime = System.nanoTime();
}
}
final void recordExit() {
if (--recursionDepth == 0) {
elapsedTime += System.nanoTime() - startTime;
counter++;
}
}
}
private Map<String, Timer> timers;
private Map<String, Integer> counters;
private Profiler() {
timers = new HashMap<String, Timer>();
counters = new HashMap<String, Integer>();
}
private static ThreadLocal<Profiler> threadProfiler = new ThreadLocal<Profiler>();
/**
*
* @param name
*/
public static void startTimer(String name) {
Profiler profiler = threadProfiler.get();
if (profiler != null) {
Timer timer = profiler.timers.get(name);
if (timer == null) {
timer = new Timer();
profiler.timers.put(name, timer);
}
timer.recordEntry();
}
}
public static void stopTimer(String name) {
Profiler profiler = threadProfiler.get();
if (profiler != null) {
Timer timer = profiler.timers.get(name);
timer.recordExit();
}
}
public static void incrementCounter(String name) {
Profiler profiler = threadProfiler.get();
if (profiler != null) {
Integer n = profiler.counters.get(name);
if (n == null) {
n = 1;
} else {
n = n.intValue() + 1;
}
profiler.counters.put(name, n);
}
}
public static void activate() {
threadProfiler.set(new Profiler());
}
public static void deactivate() {
threadProfiler.set(null);
}
public static void printStats() {
Profiler profiler = threadProfiler.get();
if (profiler != null) {
List<Map.Entry<String, Timer>> list =
new ArrayList<Map.Entry<String, Timer>>(profiler.timers.entrySet());
Comparator<Map.Entry<String, Timer>> c = new Comparator<Map.Entry<String, Timer>>() {
public int compare(Entry<String, Timer> o1, Entry<String, Timer> o2) {
long diff = o2.getValue().getElapsedTime() - o1.getValue().getElapsedTime();
return diff < 0 ? -1 : diff > 0 ? 1 : 0;
}
};
Collections.sort(list, c);
System.out.println("==="); //$NON-NLS-1$
for (Entry<String, Timer> item : list) {
System.out.println("===\t" + ((item.getValue().getElapsedTime() + 500000) / 1000000) + //$NON-NLS-1$
"\t"+ item.getValue().getCounter() + "\t" + item.getKey()); //$NON-NLS-1$ //$NON-NLS-2$
}
if (!profiler.counters.isEmpty()) {
List<Map.Entry<String, Integer>> keyList =
new ArrayList<Map.Entry<String, Integer>>(profiler.counters.entrySet());
Comparator<Map.Entry<String, Integer>> c2 = new Comparator<Map.Entry<String, Integer>>() {
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return o2.getValue().intValue() - o1.getValue().intValue();
}
};
Collections.sort(keyList, c2);
System.out.println("==="); //$NON-NLS-1$
System.out.println("===\t" + profiler.counters.size() + " counters"); //$NON-NLS-1$ //$NON-NLS-2$
for (Entry<String, Integer> item : keyList) {
System.out.println("===\t" + item.getValue().intValue() + "\t" + item.getKey()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
}
}