時間パフォーマンスの測定には、どのJavaクラスを使用する必要がありますか?
(任意の日付/時間クラスを使用できますが、私が尋ねている理由は.Netにあり、この目的のために指定された ストップウォッチ クラスがあります)
Spring Frameworkには優れた StopWatch
class があります。
StopWatch stopWatch = new StopWatch("My Stop Watch");
stopWatch.start("initializing");
Thread.sleep(2000); // simulated work
stopWatch.stop();
stopWatch.start("processing");
Thread.sleep(5000); // simulated work
stopWatch.stop();
stopWatch.start("finalizing");
Thread.sleep(3000); // simulated work
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
これにより、以下が生成されます。
StopWatch 'My Stop Watch':実行時間(ミリ秒)= 10000 -------------------------- --------------- ms%タスク名 --------------------- -------------------- 02000 020%初期化 05000 050%処理 03000 030%ファイナライズ
Java.lang.System.nanoTime()
または、Apache commonsで提供されているStopWatchを使用できます。このクラスはJava.lang.System.currentTimeMillis()を使用します
http://commons.Apache.org/lang/api-release/org/Apache/commons/lang/time/StopWatch.html
これは、StopWatchを使用して、専用メソッドに注釈を付けて複数の測定値を設定する方法の例です。非常に便利で、非常に簡単に測定できます。複数の埋め込み呼び出し/操作などのサービス呼び出し。
StopWatchHierarchy
package ch.vii.spring.aop;
import Java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
@Component
public class ProfilingMethodInterceptor implements MethodInterceptor {
private static final Logger log = LoggerFactory.getLogger(ProfilingMethodInterceptor.class);
public Object invoke(MethodInvocation invocation) throws Throwable {
if (log.isInfoEnabled()) {
String stopWatchName = invocation.getMethod().toGenericString();
StopWatchHierarchy stopWatch = StopWatchHierarchy.getStopWatchHierarchy(stopWatchName);
String taskName = invocation.getMethod().getName();
stopWatch.start(taskName);
try {
return invocation.proceed();
} finally {
stopWatch.stop();
}
} else {
return invocation.proceed();
}
}
static class StopWatchHierarchy {
private static final ThreadLocal<StopWatchHierarchy> stopwatchLocal = new ThreadLocal<StopWatchHierarchy>();
private static final IndentStack indentStack = new IndentStack();
static StopWatchHierarchy getStopWatchHierarchy(String id) {
StopWatchHierarchy stopWatch = stopwatchLocal.get();
if (stopWatch == null) {
stopWatch = new StopWatchHierarchy(id);
stopwatchLocal.set(stopWatch);
}
return stopWatch;
}
static void reset() {
stopwatchLocal.set(null);
}
final StopWatch stopWatch;
final Stack stack;
StopWatchHierarchy(String id) {
stopWatch = new StopWatch(id);
stack = new Stack();
}
void start(String taskName) {
if (stopWatch.isRunning()) {
stopWatch.stop();
}
taskName = indentStack.get(stack.size) + taskName;
stack.Push(taskName);
stopWatch.start(taskName);
}
void stop() {
stopWatch.stop();
stack.pop();
if (stack.isEmpty()) {
log.info(stopWatch.prettyPrint());
StopWatchHierarchy.reset();
} else {
stopWatch.start(stack.get());
}
}
}
static class Stack {
private int size = 0;
String elements[];
public Stack() {
elements = new String[10];
}
public void Push(String e) {
if (size == elements.length) {
ensureCapa();
}
elements[size++] = e;
}
public String pop() {
String e = elements[--size];
elements[size] = null;
return e;
}
public String get() {
return elements[size - 1];
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapa() {
int newSize = elements.length * 2;
elements = Arrays.copyOf(elements, newSize);
}
}
static class IndentStack {
String elements[] = new String[0];
public String get(int index) {
if (index >= elements.length) {
ensureCapa(index + 10);
}
return elements[index];
}
private void ensureCapa(int newSize) {
int oldSize = elements.length;
elements = Arrays.copyOf(elements, newSize);
for (int i = oldSize; i < elements.length; i++) {
elements[i] = new String(new char[i]).replace("\0", "| ");
}
}
}
}
顧問
package ch.vii.spring.aop;
import Java.lang.reflect.Method;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ProfilingAdvisor extends AbstractPointcutAdvisor {
private static final long serialVersionUID = 1L;
private final StaticMethodMatcherPointcut pointcut = new StaticMethodMatcherPointcut() {
public boolean matches(Method method, Class<?> targetClass) {
return method.isAnnotationPresent(ProfileExecution.class);
}
};
@Autowired
private ProfilingMethodInterceptor interceptor;
public Pointcut getPointcut() {
return this.pointcut;
}
public Advice getAdvice() {
return this.interceptor;
}
}
ProfileExecutionアノテーション
package ch.vii.spring.aop;
import Java.lang.annotation.ElementType;
import Java.lang.annotation.Inherited;
import Java.lang.annotation.Retention;
import Java.lang.annotation.RetentionPolicy;
import Java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface ProfileExecution {
}
コードに注釈を付けます
package ch.vii.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ch.vii.spring.aop.ProfileExecution;
@Component
public class Bean {
@Autowired
InnerBean innerBean;
@ProfileExecution
public void foo() {
innerBean.innerFoo();
innerBean.innerFoo2();
innerBean.innerFoo();
}
}
public class InnerBean {
@Autowired
InnerInnerBean innerInnerBean;
@ProfileExecution
public void innerFoo() {
}
@ProfileExecution
public void innerFoo2() {
innerInnerBean.innerInnerFoo();
innerInnerBean.innerInnerFoo();
innerInnerBean.innerInnerFoo();
}
}
出力
09:58:39.627 [main] INFO c.v.s.aop.ProfilingMethodInterceptor - StopWatch 'public void ch.vii.spring.Bean.foo()': running time (millis) = 215
-----------------------------------------
ms % Task name
-----------------------------------------
00018 008 % foo
00026 012 % | innerFoo
00001 000 % foo
00016 007 % | innerFoo2
00038 018 % | | innerInnerFoo
00000 000 % | innerFoo2
00024 011 % | | innerInnerFoo
00028 013 % | innerFoo2
00024 011 % | | innerInnerFoo
00029 013 % | innerFoo2
00000 000 % foo
00011 005 % | innerFoo
00000 000 % foo
Perf4jを確認してください。春のストップウォッチは、主に地元の開発のためのものです。 Perf4jは、POCタイプのタイミングと実稼働環境の両方をサポートできます。
測定するだけの場合は、ストップウォッチクラス、または単にストップウォッチを使用します。
より高速にしたい場合は、 これを考慮してください 。
JDK 9+を使用している場合、Flight Recorderを使用できます。オーバーヘッドが非常に低く、タイミングに不変TSCを使用します。これはSystem.nanoTime()よりも邪魔になりません。
@StackTrace(false)
static class StopWatch extends Event {
int fib;
}
public static void main(String... args) throws IOException {
Recording r = new Recording();
r.start();
for (int i = 0; i < 500000; i++) {
StopWatch s = new StopWatch();
s.begin();
s.fib = fib(i%100);
s.commit();
}
r.stop();
Path p = Paths.get("recording.jfr");
r.dump(p);
for (RecordedEvent e : RecordingFile.readAllEvents(p)) {
System.out.println(e.getValue("fib") + " " + e.getDuration().toNanos() + " ns");
}
}
コマンドラインから記録を開始し(-XX:StartFlightRecording)、構成ファイル(.jfc)でイベントを有効にすることもできます(デフォルトで無効にした場合は、@ Enable(false))。
そのようにして、JITは通常、StopWatch呼び出し(エスケープ分析、インライン化、デッドコード除去など)を最適化するため、何かを測定する場合にのみペナルティを支払います。
あなたはSystem.currentTimeMillis()を試すことができますが、良いプロファイリングEclipseやnetbeansなど、いくつかの有名なIDEでのオプション。また、IDEから離れて、パフォーマンス測定タスクで standalone profilers を試すことができます。プロファイラーを使用すると、System.currentTimeMillis()を使用するよりも良い結果が得られると思います。
System.Diagnostics.Stopwatchのようにティック(経過ティック)を取得する場合は、System.nanoTime()を使用するのが最善です。その後、ナノ秒をティックに変換する必要があり(1ティック= 100ナノ秒)、その後、変換を開始しますnanosとmillis、secs、mins、hours、そして最後にElapsed()メソッド(hh:mm:ss.ssssssss)のようなTime表現に出力をフォーマットしますが、Javaは3ミリ秒(hh:mm:ss.sss)のみを使用するため、フォーマットも同様に調整する必要があります。
Javaから取得できるストップウォッチクラスを1つ作成しました: http://carlosqt.blogspot.com/2011/05/stopwatch-class-for-Java.html
例:
package stopwatchapp;
import Java.math.BigInteger;
public class StopwatchApp {
public static void main(String[] args) {
Stopwatch timer = new Stopwatch();
timer.start();
Fibonacci(40);
timer.stop();
System.out.println("Elapsed time in ticks: "
+ timer.getElapsedTicks());
System.out.println("Elapsed time in milliseconds: "
+ timer.getElapsedMilliseconds());
System.out.println("Elapsed time in seconds: "
+ timer.getElapsedSeconds());
System.out.println("Elapsed time in minutes: "
+ timer.getElapsedMinutes());
System.out.println("Elapsed time in hours: "
+ timer.getElapsedHours());
System.out.println("Elapsed time with format: "
+ timer.getElapsed());
}
private static BigInteger Fibonacci(int n)
{
if (n < 2)
return BigInteger.ONE;
else
return Fibonacci(n - 1).add(Fibonacci(n - 2));
}
}
出力:
// Elapsed time in ticks: 33432284
// Elapsed time in milliseconds: 3343
// Elapsed time in seconds: 3
// Elapsed time in minutes: 0
// Elapsed time in hours: 0
// Elapsed time with format: 00:00:03.3432284
お役に立てれば。