blob: 3f7d9380f6c6b32e2538b37364d13ddfb0d086ee [file] [log] [blame]
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.google.dart.compiler.metrics;
import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.atomic.AtomicLong;
/**
* Collection of compiler metrics.
*/
public final class CompilerMetrics {
// TODO: Consider refactoring this class so each subsystem has it own metrics class.
public static long getCPUTime() {
return System.currentTimeMillis() * 1000000;
}
/**
* Returns the current thread's CPU time or -1 if this is not supported.
*/
public static long getThreadTime() {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
if (threadMXBean.isThreadCpuTimeSupported()) {
return threadMXBean.getCurrentThreadCpuTime();
}
return -1;
}
private static double nanoToMillis(long nanoTime) {
return nanoTime / 1000000.0d;
}
private AtomicLong charactersParsed = new AtomicLong();
private AtomicLong charactersParsedExcludingComments = new AtomicLong();
private long compileLibrariesTime = 0L;
private long compileLibrariesTimeStart = 0L;
private AtomicLong linesParsed = new AtomicLong();
private AtomicLong linesParsedExcludingComments = new AtomicLong();
private long milliEndTime = -1;
private final long milliStartTime;
private long nanoParseWallTime = 0;
private AtomicLong nanoTotalParseTime = new AtomicLong();
private long nativeLibCharCount;
// Parser metrics
private AtomicLong unitsParsed = new AtomicLong();
private long updateAndResolveTime = 0L;
// Timing metrics for complete stages
private long updateAndResolveTimeStart = 0L;
public CompilerMetrics() {
this.milliStartTime = System.currentTimeMillis();
}
/**
* Accumulate more parsing time. TODO: Once the parser gets cleaned up we should be able to
* integrate this with unit parsed.
*/
public void addParseTimeNano(long nanoTotalParseTime) {
this.nanoTotalParseTime.addAndGet(nanoTotalParseTime);
}
public void addParseWallTimeNano( long nanoWallParseTime) {
this.nanoParseWallTime = nanoWallParseTime;
}
public void done() {
if (milliEndTime == -1) {
milliEndTime = System.currentTimeMillis();
}
}
public void endCompileLibrariesTime() {
compileLibrariesTime = System.currentTimeMillis() - compileLibrariesTimeStart;
}
public void endUpdateAndResolveTime() {
updateAndResolveTime = System.currentTimeMillis() - updateAndResolveTimeStart;
}
public long getCompileLibrariesTime() {
return compileLibrariesTime;
}
public long getJSNativeLibCharSize() {
return nativeLibCharCount;
}
public double getLinesPerMS() {
return getNumLinesParsed() / getTotalCompilationTime();
}
public double getNonCommentLinesPerMS() {
return getNumNonCommentLines() / getTotalCompilationTime();
}
public long getNumCharsParsed() {
return charactersParsed.get();
}
public long getNumLinesParsed() {
return linesParsed.get();
}
public long getNumNonCommentChars() {
return charactersParsedExcludingComments.get();
}
public long getNumNonCommentLines() {
return linesParsedExcludingComments.get();
}
public double getNumUnitsParsed() {
return unitsParsed.get();
}
public double getParseTime() {
return nanoToMillis(nanoTotalParseTime.get());
}
public double getParseWallTime() {
return nanoToMillis(nanoParseWallTime);
}
public double getPercentCharsConsumedByNativeLibraries() {
return (getJSNativeLibCharSize() / getNumCharsParsed()) * 100d;
}
public double getPercentTimeParsing() {
return getParseTime() / getTotalCompilationTime();
}
public double getTimeSpentPerUnit() {
if (getNumUnitsParsed() == 0) {
return 0;
}
return getTotalCompilationTime() / getNumUnitsParsed();
}
public double getTotalCompilationTime() {
return milliEndTime - milliStartTime;
}
public long getUpdateAndResolveTime() {
return updateAndResolveTime;
}
public void startCompileLibrariesTime() {
compileLibrariesTimeStart = System.currentTimeMillis();
}
public void startUpdateAndResolveTime() {
updateAndResolveTimeStart = System.currentTimeMillis();
}
public void unitParsed(int charactersParsed, int charactersParsedExcludingComments,
int linesParsed, int linesParsedExcludingComments) {
this.unitsParsed.incrementAndGet();
this.charactersParsed.addAndGet(charactersParsed);
this.charactersParsedExcludingComments.addAndGet(charactersParsedExcludingComments);
this.linesParsed.addAndGet(linesParsed);
this.linesParsedExcludingComments.addAndGet(linesParsedExcludingComments);
}
/**
* Writes the metrics to the {@link PrintStream}.
*/
public void write(PrintStream out) {
/* This is mainly for the metrics system. Units should be encoded in
* the label name and end up as the benchmark names.
*/
done();
out.format("Compile-time-total-ms : %1$.2f%n", getTotalCompilationTime());
out.format("# Update-and-resolve-time-ms : %d\n", getUpdateAndResolveTime());
out.format("# Compile-libraries-time-ms : %d\n", getCompileLibrariesTime());
out.println("# Compile-time-unit-average-ms : " + getTimeSpentPerUnit());
out.format("# Parse-wall-time-ms : %1$.2f%n", getParseWallTime());
out.format("# Parse-time-ms : %1$.2f%n", getParseTime());
out.println("# Parsed-units : " + getNumUnitsParsed());
out.println("# Parsed-src-chars : " + getNumCharsParsed());
out.println("# Parsed-src-lines : " + getNumLinesParsed());
out.println("# Parsed-code-chars : " + getNumNonCommentChars());
out.println("# Parsed-code-lines : " + getNumNonCommentLines());
double jsNativeLibCharSize = (getJSNativeLibCharSize() == -1) ? 0 : getJSNativeLibCharSize();
out.println("# Output-js-native-lib-chars : " + jsNativeLibCharSize );
out.println("# Processed-total-lines-ms : " + getLinesPerMS());
out.println("# Processed-code-lines-ms : " + getNonCommentLinesPerMS());
out.println("# Ratio-parsing-compile-percent : " + getPercentTimeParsing() * 100);
}
}