View Javadoc

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