You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2016/02/04 00:27:52 UTC
[math] Improved formatting of the benchmarking report.
Repository: commons-math
Updated Branches:
refs/heads/master 0952cee35 -> e0b2c86c8
Improved formatting of the benchmarking report.
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/e0b2c86c
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/e0b2c86c
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/e0b2c86c
Branch: refs/heads/master
Commit: e0b2c86c8754312d1e89307fbf84e6efbfa9fe0b
Parents: 0952cee
Author: Gilles <er...@apache.org>
Authored: Thu Feb 4 00:25:56 2016 +0100
Committer: Gilles <er...@apache.org>
Committed: Thu Feb 4 00:25:56 2016 +0100
----------------------------------------------------------------------
.../org/apache/commons/math4/PerfTestUtils.java | 127 +++++++++++++++++--
1 file changed, 119 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/e0b2c86c/src/test/java/org/apache/commons/math4/PerfTestUtils.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/PerfTestUtils.java b/src/test/java/org/apache/commons/math4/PerfTestUtils.java
index 7af8088..2064f53 100644
--- a/src/test/java/org/apache/commons/math4/PerfTestUtils.java
+++ b/src/test/java/org/apache/commons/math4/PerfTestUtils.java
@@ -16,12 +16,16 @@
*/
package org.apache.commons.math4;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.regex.MatchResult;
import java.util.concurrent.Callable;
import org.apache.commons.math4.util.MathArrays;
import org.apache.commons.math4.random.RandomGenerator;
import org.apache.commons.math4.random.Well19937c;
import org.apache.commons.math4.exception.MathIllegalStateException;
+import org.apache.commons.math4.exception.NumberIsTooLargeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
import org.apache.commons.math4.stat.descriptive.StatisticalSummary;
import org.apache.commons.math4.stat.descriptive.SummaryStatistics;
@@ -30,6 +34,18 @@ import org.apache.commons.math4.stat.descriptive.SummaryStatistics;
* Simple benchmarking utilities.
*/
public class PerfTestUtils {
+ /** Formatting. */
+ private static final int DEFAULT_MAX_NAME_WIDTH = 45;
+ /** Formatting. */
+ private static final String ELLIPSIS = "...";
+ /** Formatting. */
+ private static final String TO_STRING_MEMORY_ADDRESS_REGEX = "@\\p{XDigit}{1,8}";
+ /** Formatting. */
+ private static final String JAVA_IDENTIFIER_REGEX =
+ "(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*\\.)*\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*";
+ /** Formatting. */
+ private static final Pattern JAVA_IDENTIFIER_PATTERN =
+ Pattern.compile(JAVA_IDENTIFIER_REGEX);
/** Nanoseconds to milliseconds conversion factor ({@value}). */
public static final double NANO_TO_MILLI = 1e-6;
/** Default number of code repeat per timed block. */
@@ -159,6 +175,7 @@ public class PerfTestUtils {
* {@link #time(int,int,boolean,Callable[]) time} method.
*
* @param title Title of the test (for the report).
+ * @param maxNameWidth Maximum width of the first column of the report.
* @param repeatChunk Each timing measurement will done done for that
* number of repeats of the code.
* @param repeatStat Timing will be averaged over that number of runs.
@@ -172,6 +189,7 @@ public class PerfTestUtils {
*/
@SuppressWarnings("boxing")
public static StatisticalSummary[] timeAndReport(String title,
+ int maxNameWidth,
int repeatChunk,
int repeatStat,
boolean runGC,
@@ -179,20 +197,26 @@ public class PerfTestUtils {
// Header format.
final String hFormat = "%s (calls per timed block: %d, timed blocks: %d, time unit: ms)";
+ // TODO: user-defined parameter?
+ final boolean removePackageName = false;
+
// Width of the longest name.
int nameLength = 0;
for (RunTest m : methods) {
- int len = m.getName().length();
+ int len = shorten(m.getName(), removePackageName).length();
if (len > nameLength) {
nameLength = len;
}
}
- final String nameLengthFormat = "%" + nameLength + "s";
+ final int actualNameLength = nameLength < maxNameWidth ?
+ nameLength :
+ maxNameWidth;
+ final String nameLengthFormat = "%" + actualNameLength + "s";
// Column format.
- final String cFormat = nameLengthFormat + " %14s %14s %10s %10s %15s";
+ final String cFormat = nameLengthFormat + " %9s %7s %10s %5s %4s %10s";
// Result format.
- final String format = nameLengthFormat + " %.8e %.8e %.4e %.4e % .8e";
+ final String format = nameLengthFormat + " %.3e %.1e %.4e %.3f %.2f %.4e";
System.out.println(String.format(hFormat,
title,
@@ -201,9 +225,10 @@ public class PerfTestUtils {
System.out.println(String.format(cFormat,
"name",
"time/call",
- "std error",
+ "std dev",
"total time",
"ratio",
+ "cv",
"difference"));
final StatisticalSummary[] time = time(repeatChunk,
repeatStat,
@@ -213,12 +238,18 @@ public class PerfTestUtils {
for (int i = 0, max = time.length; i < max; i++) {
final StatisticalSummary s = time[i];
final double sum = s.getSum() * repeatChunk;
+ final double mean = s.getMean();
+ final double sigma = s.getStandardDeviation();
System.out.println(String.format(format,
- methods[i].getName(),
- s.getMean(),
- s.getStandardDeviation(),
+ truncate(shorten(methods[i].getName(),
+ removePackageName),
+ actualNameLength,
+ ELLIPSIS),
+ mean,
+ sigma,
sum,
sum / refSum,
+ sigma / mean,
sum - refSum));
}
@@ -240,6 +271,7 @@ public class PerfTestUtils {
public static StatisticalSummary[] timeAndReport(String title,
RunTest ... methods) {
return timeAndReport(title,
+ DEFAULT_MAX_NAME_WIDTH,
DEFAULT_REPEAT_CHUNK,
DEFAULT_REPEAT_STAT,
false,
@@ -269,4 +301,83 @@ public class PerfTestUtils {
/** {@inheritDoc} */
public abstract Double call() throws Exception;
}
+
+ /**
+ * Truncates a string so that it will not be longer than the
+ * specified length.
+ *
+ * @param str String to truncate.
+ * @param maxLength Maximum length.
+ * @param ellipsis String to use in place of the part being removed
+ * from the original string.
+ * @return the truncated string.
+ * @throws NumberIsTooLargeException if the length of {@code ellipsis}
+ * is larger than {@code maxLength - 2}.
+ */
+ private static String truncate(String str,
+ int maxLength,
+ String ellipsis) {
+ final int ellSize = ellipsis.length();
+ if (ellSize > maxLength - 2) {
+ throw new NumberIsTooLargeException(ellSize, maxLength - 2, false);
+ }
+
+ final int strSize = str.length();
+ if (strSize <= maxLength) {
+ // Size is OK.
+ return str;
+ }
+
+ return str.substring(0, maxLength - ellSize) + ellipsis;
+ }
+
+ /**
+ * Shortens a string.
+ * It will shorten package names and remove memory addresses
+ * that appear in an instance's name.
+ *
+ * @param str Orginal string.
+ * @param removePackageName Whether package name part of a
+ * fully-quallified name should be removed entirely.
+ * @return the shortened string.
+ */
+ private static String shorten(String str,
+ boolean removePackageName) {
+ final Matcher m = JAVA_IDENTIFIER_PATTERN.matcher(str);
+ final StringBuffer sb = new StringBuffer();
+ while (m.find()) {
+ final MatchResult r = m.toMatchResult();
+ m.appendReplacement(sb, shortenPackageName(r.group(),
+ removePackageName));
+ }
+ m.appendTail(sb);
+
+ return sb.toString().replaceAll(TO_STRING_MEMORY_ADDRESS_REGEX, "");
+ }
+
+ /**
+ * Shortens package part of the name of a class.
+ *
+ * @param name Class name.
+ * @param remove Whether package name part of a fully-qualified
+ * name should be removed entirely.
+ * @return the shortened name.
+ */
+ private static String shortenPackageName(String name,
+ boolean remove) {
+ final String[] comp = name.split("\\.");
+ final int last = comp.length - 1;
+
+ if (remove) {
+ return comp[last];
+ }
+
+ final StringBuilder s = new StringBuilder();
+ for (int i = 0; i < last; i++) {
+ s.append(comp[i].substring(0, 1)).append(".");
+ }
+ s.append(comp[last]);
+
+ return s.toString();
+ }
}