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.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       * @param args String[]
44       * @param name String
45       * @return boolean
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       * @param args String[]
59       * @param name String
60       * @param defaultValue String
61       * @return String
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       * @param args String[]
75       * @throws RuleSetNotFoundException
76       * @throws IOException
77       * @throws PMDException
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      * @param parser Parser
123      * @param dataSources List<DataSource>
124      * @param debug boolean
125      * @throws IOException
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      * @param languageVersion LanguageVersion
148      * @param ruleSet RuleSet
149      * @param dataSources List<DataSource>
150      * @param results Set<RuleDuration>
151      * @param debug boolean
152      * @throws PMDException
153      * @throws IOException
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      * @param type Benchmark
191      * @param time long
192      * @param count long
193      */
194     public static void mark(Benchmark type, long time, long count) {
195         mark(type, null, time, count);
196     }
197 
198     /**
199      *
200      * @param type Benchmark
201      * @param name String
202      * @param time long
203      * @param count long
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      * @return Map<String,BenchmarkResult>
229      */
230     public static Map<String, BenchmarkResult> values() {
231     	return BenchmarksByName;
232     }
233 }