Skip to content

Commit

Permalink
add RunnableMatrix.java and PerfHtmlBuilder.java.
Browse files Browse the repository at this point in the history
  • Loading branch information
CalvinChen committed May 29, 2012
1 parent 34d9075 commit 12a318b
Show file tree
Hide file tree
Showing 7 changed files with 729 additions and 85 deletions.
6 changes: 6 additions & 0 deletions core-lang/pom.xml
Expand Up @@ -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>
279 changes: 266 additions & 13 deletions core-lang/src/main/java/bingo/lang/testing/Perf.java
Expand Up @@ -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){
Expand All @@ -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;
}

}
73 changes: 73 additions & 0 deletions core-lang/src/main/java/bingo/lang/testing/PerfHtmlBuilder.java
@@ -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;
}
}

0 comments on commit 12a318b

Please sign in to comment.