Permalink
Browse files

add RunnableMatrix.java and PerfHtmlBuilder.java.

  • Loading branch information...
1 parent 34d9075 commit 12a318b081039e453e185173ed6a73bfc2ecdf03 @CalvinChen CalvinChen committed May 29, 2012
View
@@ -26,5 +26,11 @@
<version>1.6.1</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>dom4j</groupId>
+ <artifactId>dom4j</artifactId>
+ <version>1.6.1</version>
+ </dependency>
</dependencies>
</project>
@@ -15,39 +15,179 @@
*/
package bingo.lang.testing;
-import bingo.lang.StopWatch;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Date;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.io.XMLWriter;
+import org.xml.sax.SAXException;
+
import bingo.lang.Strings;
/**
- * Performance measurements utiltiy for unit test.
+ * Performance measurements utility for unit test.
*/
public final class Perf {
- public static void run(String test, Runnable action){
- run(test, action, 1);
- }
+ public static final int TO_CONSOLE = 0;
+ public static final int TO_HTML = 1;
+ public static final int TO_CONSOLE_AND_HTML = 2;
+
+ public static final String DEFAULT_PROJECT_NAME = "anonymous";
+ public static final String DEFAULT_FILE_NAME = "testing.html";
+ public static final String DEFAULT_DIR_NAME = "perf";
+
+ private String projectName = DEFAULT_PROJECT_NAME;
+ private Runnable runnableThing;
+ private int showResultTo = TO_CONSOLE;
+ private String fileName;
+
+ private PerfResult perfResult;
+
+ private int runnableType = IS_SIMPLE_RUNNABLE;
+ public static final int IS_SIMPLE_RUNNABLE = 0;
+ public static final int IS_RUNNABLE_GROUP = 1;
+ public static final int IS_RUNNABLE_MATRIX = 2;
- public static void run(String test,Runnable action,int times){
+ public Perf(){
+ this(DEFAULT_PROJECT_NAME, null, TO_CONSOLE, null);
+ }
+
+ public Perf(Runnable runnable){
+ this(DEFAULT_PROJECT_NAME, runnable, TO_CONSOLE, null);
+ }
+
+ public Perf(String projectName, Runnable runnable, int showResultTo, String fileName){
+ this.projectName = projectName;
+ checkAndSetRunnableType(runnable);
+ this.runnableThing = runnable;
+ this.showResultTo = showResultTo;
+ this.fileName = fileName;
+ }
+
+ public void run(){
+ if(null == runnableThing){
+ throw new RuntimeException("the runnable thing could not be null.");
+ }
+ if(runnableType == IS_RUNNABLE_GROUP || runnableType == IS_SIMPLE_RUNNABLE){
+ runGroup();
+ }
+ if(runnableType == IS_RUNNABLE_MATRIX){
+ runMatrix();
+ }
+ }
+
+ /**
+ * run a runnable group.
+ */
+ private void runGroup(){
/* wrapped with runnable group */
- String name = RunnableGroup.tryToGetName(action);
- times = RunnableGroup.tryToGetRunTimes(action);
+ String name = RunnableGroup.tryToGetName(runnableThing);
+ int times = RunnableGroup.tryToGetRunTimes(runnableThing);
- RunnableGroup runnableGroup = new RunnableGroup(name, action, times);
+ RunnableGroup runnableGroup = new RunnableGroup(name, times, runnableThing);
/* warm up */
runnableGroup.run();
runnableGroup.run();
- Perf.toConsole(test, runnableGroup.getPerfResult());
+ perfResult = runnableGroup.getPerfResult();
+
+ if(showResultTo == TO_CONSOLE){
+ groupToConsole();
+ }
+
+ if(showResultTo == TO_HTML){
+ groupToHtml();
+ }
+
+ if(showResultTo == TO_CONSOLE_AND_HTML){
+ groupToConsole();
+ groupToHtml();
+ }
}
- public static void toConsole(String name, PerfResult perfResult){
- System.out.println("PROJECT: " + name);
+ private void runMatrix(){
+ RunnableMatrix matrix = (RunnableMatrix) runnableThing;
+
+ matrix.run();
+
+ PerfResult[][] resultMatrix = matrix.getResultMatrix();
+
+ if(showResultTo == TO_CONSOLE){
+ matrixToConsole(resultMatrix);
+ }
+
+ if(showResultTo == TO_HTML){
+ matrixToHtml(resultMatrix);
+ }
+
+ if(showResultTo == TO_CONSOLE_AND_HTML){
+ matrixToConsole(resultMatrix);
+ matrixToHtml(resultMatrix);
+ }
+ }
+
+ private void matrixToHtml(PerfResult[][] resultMatrix) {
+ Document doc = PerfHtmlBuilder.buildUpMatrixHtml(projectName, resultMatrix);
+ writeToHtml(doc);
+ }
+
+
+
+ private void matrixToConsole(PerfResult[][] resultMatrix) {
+ System.out.println("------------------------------------------------");
+ for (int i = -1; i < resultMatrix.length; i++) {
+ if(-1 == i){
+ System.out.print("\t");
+ for (int k = 0; k < resultMatrix[0].length; k++) {
+ System.out.print(resultMatrix[0][k].getName() + "\t");
+ }
+ System.out.println();
+ continue;
+ } else {
+ System.out.print(resultMatrix[i][0].getRunTimes() + "\t");
+ }
+ for (int j = 0; j < resultMatrix[i].length; j++) {
+ System.out.print(resultMatrix[i][j].getElapsedNanoseconds() + "\t\t");
+ }
+ System.out.println();
+ }
+ }
+
+ /**
+ * show the specified named {@link PerfResult} to console.
+ * @param projectName name of this {@link PerfResult}.
+ * @param perfResult the specified {@link PerfResult}.
+ */
+ public void groupToConsole(){
+ System.out.println("PROJECT: " + projectName);
toConsole(perfResult.getChildren().get(0), "");
}
- private static void toConsole(PerfResult perfResult, String prefix){
+ public void groupToHtml(){
+ Document doc = buildUpGroupHtml();
+ writeToHtml(doc);
+ }
+
+ private void checkAndSetRunnableType(Runnable runnable){
+ if(runnable instanceof RunnableMatrix){
+ this.runnableType = IS_RUNNABLE_MATRIX;
+ return;
+ }
+ if(runnable instanceof RunnableGroup){
+ this.runnableType = IS_RUNNABLE_GROUP;
+ return;
+ }
+ this.runnableType = IS_SIMPLE_RUNNABLE;
+ }
+
+ private void toConsole(PerfResult perfResult, String prefix){
System.out.println(prefix + perfResult.toString());
prefix += " ";
if(perfResult.isEnd() == false){
@@ -56,4 +196,117 @@ private static void toConsole(PerfResult perfResult, String prefix){
}
}
}
+
+ private Document buildUpGroupHtml(){
+ Document doc = DocumentHelper.createDocument();
+ Element html = doc.addElement("html");
+ html.addAttribute("lang", "en");
+ Element head = html.addElement("head");
+ Element link = head.addElement("link");
+ link.addAttribute("href", "http://twitter.github.com/bootstrap/assets/css/bootstrap.css");
+ link.addAttribute("rel", "stylesheet");
+ Element body = html.addElement("body");
+ body.addElement("H2").addText(projectName);
+ Element table = body.addElement("table");
+ table.addAttribute("class", "table table-bordered table-striped");
+ Element thead = table.addElement("thead");
+ Element tr = thead.addElement("tr");
+ tr.addElement("th").addText("Hierarchy");
+ tr.addElement("th").addText("Name");
+ tr.addElement("th").addText("Run Times");
+ tr.addElement("th").addText("ms");
+ tr.addElement("th").addText("ns");
+ Element tbody = table.addElement("tbody");
+ buildUpGroupRow("|", 0, perfResult, tbody);
+ return doc;
+ }
+
+ private void buildUpGroupRow(String prefix, int number, PerfResult perfResult, Element tbody){
+ if(number != 0){
+ Element tr = tbody.addElement("tr");
+ tr.addElement("td").addText(prefix);
+ prefix += "--" + number + "--|";
+ tr.addElement("td").addText(perfResult.getName());
+ tr.addElement("td").addText(perfResult.getRunTimes() + "");
+ tr.addElement("td").addText(perfResult.getElapsedMilliseconds() + "");
+ tr.addElement("td").addText(perfResult.getElapsedNanoseconds() + "");
+ }
+ number++;
+
+ if(perfResult.isEnd() == false){
+ for (PerfResult perf : perfResult.getChildren()) {
+ buildUpGroupRow(prefix, number, perf, tbody);
+ }
+ }
+ }
+
+ private void writeToHtml(Document document){
+ XMLWriter writer = null;
+ try{
+ File dir = new File(DEFAULT_DIR_NAME);
+ File file = null;
+ dir.mkdir();
+ if(DEFAULT_PROJECT_NAME.equals(projectName)){
+ file = new File(dir, DEFAULT_FILE_NAME);
+ } else {
+ file = new File(dir, projectName + ".html");
+ }
+ file.createNewFile();
+ writer = new XMLWriter(new FileWriter(file));
+ writer.write(document);
+ } catch (Exception e) {
+ throw new RuntimeException("error when generating HTML file.");
+ } finally {
+ if(null != writer){
+ try {
+ writer.close();
+ } catch (IOException e) {
+ throw new RuntimeException("error when closing HTML file.");
+ }
+ }
+ }
+ }
+
+ /* getter and setter */
+
+ public String getProjectName() {
+ return projectName;
+ }
+
+ public void setProjectName(String projectName) {
+ this.projectName = projectName;
+ }
+
+ public Runnable getRunnableThing() {
+ return runnableThing;
+ }
+
+ public void setRunnableThing(Runnable runnableThing) {
+ this.runnableThing = runnableThing;
+ }
+
+ public int getShowResultTo() {
+ return showResultTo;
+ }
+
+ public void setShowResultTo(int showResultTo) {
+ this.showResultTo = showResultTo;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public int getRunnableType() {
+ return runnableType;
+ }
+
+ public void setRunnableType(int runnableType) {
+ this.runnableType = runnableType;
+ }
+
}
@@ -0,0 +1,73 @@
+package bingo.lang.testing;
+
+import java.util.Date;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
+public class PerfHtmlBuilder {
+
+ public static Document buildUpMatrixHtml(String projectName, PerfResult[][] resultMatrix) {
+ Document doc = DocumentHelper.createDocument();
+ Element html = doc.addElement("html");
+ html.addAttribute("lang", "en");
+ buildUpHead(projectName, html);
+ buildUpBody(projectName, html, resultMatrix);
+ return doc;
+ }
+
+ private static Element buildUpHead(String projectName, Element html){
+ Element head = html.addElement("head");
+ head.addElement("title").addText("The Performance Report of \"" + projectName + "\"");
+ Element link = head.addElement("link");
+ link.addAttribute("href", "http://twitter.github.com/bootstrap/assets/css/bootstrap.css");
+ link.addAttribute("rel", "stylesheet");
+ head.addElement("style").addText("body{padding:20px}");
+ return head;
+ }
+
+ private static Element buildUpBody(String projectName, Element html, PerfResult[][] resultMatrix){
+ Element body = html.addElement("body");
+ Element divContainer = body.addElement("div");
+ divContainer.addAttribute("class", "containner");
+ divContainer.addElement("H1").addText(projectName);
+ buildUpTable(divContainer, resultMatrix);
+ Element block = divContainer.addElement("blockquote");
+ block.addAttribute("class", "pull-right");
+ block.addElement("p").addText("Generated on " + new Date().toString() + ".");
+ block.addElement("small").addText("powered by bingo.core");
+ return body;
+ }
+
+ private static Element buildUpTable(Element divContainer, PerfResult[][] resultMatrix){
+ Element table = divContainer.addElement("table");
+ table.addAttribute("class", "table table-bordered table-striped");
+ Element thead = table.addElement("thead");
+ Element tr = thead.addElement("tr");
+ tr.addElement("th").addText("Repeat Time\\Code");
+ for (int i = 0; i < resultMatrix[0].length; i++) {
+ tr.addElement("th").addText(resultMatrix[0][i].getName());
+ }
+ buildUpTbody(table, resultMatrix);
+ return table;
+ }
+
+ private static Element buildUpTbody(Element table, PerfResult[][] resultMatrix){
+ Element tbody = table.addElement("tbody");
+ Element tr = null;
+ for (int i = 0; i < resultMatrix.length; i++) {
+ tr = tbody.addElement("tr");
+ tr.addElement("td").addText("")
+ .addElement("strong").addText("" + resultMatrix[i][0].getRunTimes());
+ for (int j = 0; j < resultMatrix[i].length; j++) {
+ PerfResult cell = resultMatrix[i][j];
+ tr.addElement("td").addText("")
+ .addElement("strong").addText(cell.getElapsedNanoseconds() + "")
+ .getParent().addText(" ns.(" + cell.getElapsedMilliseconds() +
+ " ms, " + (int)(cell.getElapsedNanoseconds()*1.0/cell.getRunTimes() + 0.5) + " ns each)");
+ }
+ }
+ return tbody;
+ }
+}
Oops, something went wrong.

0 comments on commit 12a318b

Please sign in to comment.