View Javadoc
1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.benchmark;
5   
6   import java.io.PrintStream;
7   import java.text.MessageFormat;
8   import java.util.ArrayList;
9   import java.util.Collections;
10  import java.util.List;
11  import java.util.Map;
12  import java.util.Set;
13  
14  import net.sourceforge.pmd.PMD;
15  import net.sourceforge.pmd.util.StringUtil;
16  
17  /**
18   *
19   *
20   */
21  public class TextReport implements BenchmarkReport {
22  
23  
24  	private static final int TIME_COLUMN		 = 48;
25  	private static final int NAME_COLUMN_WIDTH	 = 50;
26  	private static final int VALUE_COLUMN_WIDTH	 =  8;
27  
28  	/**
29  	 *
30  	 * @param stressResults Set<Result>
31  	 * @param out PrintStream
32  	 * @see net.sourceforge.pmd.benchmark.BenchmarkReport#generate(Set<Result>, PrintStream)
33  	 */
34  	public void generate(Set<RuleDuration> stressResults, PrintStream out) {
35  
36  		  out.println("=========================================================");
37            out.println("Rule\t\t\t\t\t\tTime in ms");
38            out.println("=========================================================");
39  
40            for (RuleDuration result: stressResults) {
41                StringBuilder buffer = new StringBuilder(result.rule.getName());
42                while (buffer.length() < TIME_COLUMN) {
43              	  buffer.append(' ');
44                }
45                buffer.append(result.time);
46                out.println(out.toString());
47            }
48  
49            out.println("=========================================================");
50  	}
51  
52  	/**
53  	 *
54  	 * @param benchmarksByName Map<String,BenchmarkResult>
55  	 */
56  	public void report(Map<String, BenchmarkResult> benchmarksByName) {
57  		generate(benchmarksByName, System.out);
58  	}
59  
60  	/**
61  	 *
62  	 * @param benchmarksByName Map<String,BenchmarkResult>
63  	 * @param out PrintStream
64  	 * @see net.sourceforge.pmd.benchmark.BenchmarkReport#generate(Map<String,BenchmarkResult>, PrintStream)
65  	 */
66  	public void generate(Map<String, BenchmarkResult> benchmarksByName, PrintStream out) {
67  
68  		List<BenchmarkResult> results = new ArrayList<>(benchmarksByName.values());
69  
70  		long[] totalTime = new long[Benchmark.TotalPMD.index + 1];
71  		long[] totalCount = new long[Benchmark.TotalPMD.index + 1];
72  
73  		for (BenchmarkResult benchmarkResult: results) {
74  			totalTime[benchmarkResult.type.index] += benchmarkResult.getTime();
75  			totalCount[benchmarkResult.type.index] += benchmarkResult.getCount();
76  			if (benchmarkResult.type.index < Benchmark.MeasuredTotal.index) {
77  				totalTime[Benchmark.MeasuredTotal.index] += benchmarkResult.getTime();
78  			}
79  		}
80  		results.add(new BenchmarkResult(Benchmark.RuleTotal, 		totalTime[Benchmark.RuleTotal.index], 0));
81  		results.add(new BenchmarkResult(Benchmark.RuleChainTotal, 	totalTime[Benchmark.RuleChainTotal.index], 0));
82  		results.add(new BenchmarkResult(Benchmark.MeasuredTotal, 	totalTime[Benchmark.MeasuredTotal.index], 0));
83  		results.add(new BenchmarkResult(Benchmark.NonMeasuredTotal, totalTime[Benchmark.TotalPMD.index] - totalTime[Benchmark.MeasuredTotal.index], 0));
84  		Collections.sort(results);
85  
86  		StringBuilderCR buf = new StringBuilderCR(PMD.EOL);
87  		boolean writeRuleHeader = true;
88  		boolean writeRuleChainRuleHeader = true;
89  		long ruleCount = 0;
90  		long ruleChainCount = 0;
91  
92  		for (BenchmarkResult benchmarkResult: results) {
93  			StringBuilder buf2 = new StringBuilder(benchmarkResult.name);
94  			buf2.append(':');
95  			while (buf2.length() <= NAME_COLUMN_WIDTH) {
96  				buf2.append(' ');
97  			}
98  			String result = MessageFormat.format("{0,number,0.000}", Double.valueOf(benchmarkResult.getTime()/1000000000.0));
99  			buf2.append(StringUtil.lpad(result, VALUE_COLUMN_WIDTH));
100 			if (benchmarkResult.type.index <= Benchmark.RuleChainRule.index) {
101 				buf2.append(StringUtil.lpad(MessageFormat.format("{0,number,###,###,###,###,###}", benchmarkResult.getCount()), 20));
102 			}
103 			switch (benchmarkResult.type) {
104 			case Rule:
105 				if (writeRuleHeader) {
106 					writeRuleHeader = false;
107 					buf.appendLn();
108 					buf.appendLn("---------------------------------<<< Rules >>>---------------------------------");
109 					buf.appendLn("Rule name                                       Time (secs)    # of Evaluations");
110 					buf.appendLn();
111 				}
112 				ruleCount++;
113 				break;
114 			case RuleChainRule:
115 				if (writeRuleChainRuleHeader) {
116 					writeRuleChainRuleHeader = false;
117 					buf.appendLn();
118 					buf.appendLn("----------------------------<<< RuleChain Rules >>>----------------------------");
119 					buf.appendLn("Rule name                                       Time (secs)         # of Visits");
120 					buf.appendLn();
121 				}
122 				ruleChainCount++;
123 				break;
124 			case CollectFiles:
125 				buf.appendLn();
126 				buf.appendLn("--------------------------------<<< Summary >>>--------------------------------");
127 				buf.appendLn("Segment                                         Time (secs)");
128 				buf.appendLn();
129 				break;
130 			case MeasuredTotal:
131 				String s = MessageFormat.format("{0,number,###,###,###,###,###}", ruleCount);
132 				String t = MessageFormat.format("{0,number,0.000}", ruleCount==0 ? 0 : total(totalTime,Benchmark.Rule,ruleCount));
133 				buf.appendLn("Rule Average (", s, " rules):", StringUtil.lpad(t, 37-s.length()));
134 				s = MessageFormat.format("{0,number,###,###,###,###,###}", ruleChainCount);
135 				t = MessageFormat.format("{0,number,0.000}", ruleChainCount==0 ? 0 : total(totalTime,Benchmark.RuleChainRule, ruleChainCount));
136 				buf.appendLn("RuleChain Average (", s, " rules):", StringUtil.lpad(t, 32-s.length()));
137 
138 				buf.appendLn();
139 				buf.appendLn("-----------------------------<<< Final Summary >>>-----------------------------");
140 				buf.appendLn("Total                                           Time (secs)");
141 				buf.appendLn();
142 				break;
143 			default:
144 				// Do nothing
145 				break;
146 			}
147 			buf.appendLn(buf2.toString());
148 		}
149 
150 		out.print(buf.toString());
151 	}
152 
153 	/**
154 	 *
155 	 * @param timeTotals long[]
156 	 * @param index Benchmark
157 	 * @param count long
158 	 * @return double
159 	 */
160 	private static double total(long[] timeTotals, Benchmark index, long count) {
161 		return timeTotals[index.index]/1000000000.0d/count;
162 	}
163 }