1
2
3
4 package net.sourceforge.pmd.benchmark;
5
6 import java.io.IOException;
7 import java.io.InputStreamReader;
8 import java.io.Reader;
9 import java.util.HashMap;
10 import java.util.Iterator;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14 import java.util.TreeSet;
15
16 import net.sourceforge.pmd.PMD;
17 import net.sourceforge.pmd.PMDConfiguration;
18 import net.sourceforge.pmd.PMDException;
19 import net.sourceforge.pmd.Rule;
20 import net.sourceforge.pmd.RuleContext;
21 import net.sourceforge.pmd.RuleSet;
22 import net.sourceforge.pmd.RuleSetFactory;
23 import net.sourceforge.pmd.RuleSetNotFoundException;
24 import net.sourceforge.pmd.RuleSets;
25 import net.sourceforge.pmd.SourceCodeProcessor;
26 import net.sourceforge.pmd.lang.Language;
27 import net.sourceforge.pmd.lang.LanguageFilenameFilter;
28 import net.sourceforge.pmd.lang.LanguageVersion;
29 import net.sourceforge.pmd.lang.Parser;
30 import net.sourceforge.pmd.util.FileUtil;
31 import net.sourceforge.pmd.util.StringUtil;
32 import net.sourceforge.pmd.util.datasource.DataSource;
33
34 import org.apache.commons.io.IOUtils;
35
36
37
38
39
40 public class Benchmarker {
41
42
43
44
45
46
47 private static boolean findBooleanSwitch(String[] args, String name) {
48 for (int i = 0; i < args.length; i++) {
49 if (args[i].equals(name)) {
50 return true;
51 }
52 }
53 return false;
54 }
55
56
57
58
59
60
61
62
63 private static String findOptionalStringValue(String[] args, String name, String defaultValue) {
64 for (int i = 0; i < args.length; i++) {
65 if (args[i].equals(name)) {
66 return args[i + 1];
67 }
68 }
69 return defaultValue;
70 }
71
72
73
74
75
76
77
78
79 public static void main(String[] args) throws RuleSetNotFoundException, IOException, PMDException {
80
81 String targetjdk = findOptionalStringValue(args, "--targetjdk", "1.4");
82 Language language = Language.JAVA;
83 LanguageVersion languageVersion = language.getVersion(targetjdk);
84 if (languageVersion == null) {
85 languageVersion = language.getDefaultVersion();
86 }
87
88 String srcDir = findOptionalStringValue(args, "--source-directory", "/usr/local/java/src/java/lang/");
89 List<DataSource> dataSources = FileUtil.collectFiles(srcDir, new LanguageFilenameFilter(language));
90
91 boolean debug = findBooleanSwitch(args, "--debug");
92 boolean parseOnly = findBooleanSwitch(args, "--parse-only");
93
94 if (debug) {
95 System.out.println("Using " +language.getName() + " " + languageVersion.getVersion());
96 }
97 if (parseOnly) {
98 Parser parser = PMD.parserFor(languageVersion, null);
99 parseStress(parser, dataSources, debug);
100 } else {
101 String ruleset = findOptionalStringValue(args, "--ruleset", "");
102 if (debug) {
103 System.out.println("Checking directory " + srcDir);
104 }
105 Set<RuleDuration> results = new TreeSet<RuleDuration>();
106 RuleSetFactory factory = new RuleSetFactory();
107 if (StringUtil.isNotEmpty(ruleset)) {
108 stress(languageVersion, factory.createRuleSet(ruleset), dataSources, results, debug);
109 } else {
110 Iterator<RuleSet> i = factory.getRegisteredRuleSets();
111 while (i.hasNext()) {
112 stress(languageVersion, i.next(), dataSources, results, debug);
113 }
114 }
115
116 TextReport report = new TextReport();
117 report.generate(results, System.err);
118 }
119 }
120
121
122
123
124
125
126
127 private static void parseStress(Parser parser, List<DataSource> dataSources, boolean debug) throws IOException {
128
129 long start = System.currentTimeMillis();
130
131 for (DataSource dataSource: dataSources) {
132 parser.parse(
133 dataSource.getNiceFileName(false, null),
134 new InputStreamReader(dataSource.getInputStream()
135 )
136 );
137 }
138
139 if (debug) {
140 long end = System.currentTimeMillis();
141 long elapsed = end - start;
142 System.out.println("That took " + elapsed + " ms");
143 }
144 }
145
146
147
148
149
150
151
152
153
154
155 private static void stress(LanguageVersion languageVersion, RuleSet ruleSet, List<DataSource> dataSources, Set<RuleDuration> results, boolean debug) throws PMDException, IOException {
156
157 for (Rule rule: ruleSet.getRules()) {
158 if (debug) {
159 System.out.println("Starting " + rule.getName());
160 }
161
162 RuleSet working = new RuleSet();
163 working.addRule(rule);
164 RuleSets ruleSets = new RuleSets(working);
165
166 PMDConfiguration config = new PMDConfiguration();
167 config.setDefaultLanguageVersion(languageVersion);
168
169 RuleContext ctx = new RuleContext();
170 long start = System.currentTimeMillis();
171 Reader reader = null;
172 for (DataSource dataSource: dataSources) {
173 reader = new InputStreamReader(dataSource.getInputStream());
174 ctx.setSourceCodeFilename(dataSource.getNiceFileName(false, null));
175 new SourceCodeProcessor(config).processSourceCode(reader, ruleSets, ctx);
176 IOUtils.closeQuietly(reader);
177 }
178 long end = System.currentTimeMillis();
179 long elapsed = end - start;
180 results.add(new RuleDuration(elapsed, rule));
181 if (debug) {
182 System.out.println("Done timing " + rule.getName() + "; elapsed time was " + elapsed);
183 }
184 }
185 }
186
187 private static final Map<String, BenchmarkResult> BenchmarksByName = new HashMap<String, BenchmarkResult>();
188
189
190
191
192
193
194 public static void mark(Benchmark type, long time, long count) {
195 mark(type, null, time, count);
196 }
197
198
199
200
201
202
203
204
205 public synchronized static void mark(Benchmark type, String name, long time, long count) {
206 String typeName = type.name;
207 if (typeName != null && name != null) {
208 throw new IllegalArgumentException("Name cannot be given for type: " + type);
209 } else if (typeName == null && name == null) {
210 throw new IllegalArgumentException("Name is required for type: " + type);
211 } else if (typeName == null) {
212 typeName = name;
213 }
214 BenchmarkResult benchmarkResult = BenchmarksByName.get(typeName);
215 if (benchmarkResult == null) {
216 benchmarkResult = new BenchmarkResult(type, typeName);
217 BenchmarksByName.put(typeName, benchmarkResult);
218 }
219 benchmarkResult.update(time, count);
220 }
221
222 public static void reset() {
223 BenchmarksByName.clear();
224 }
225
226
227
228
229
230 public static Map<String, BenchmarkResult> values() {
231 return BenchmarksByName;
232 }
233 }