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 }