Package lombok.ast.grammar

Source Code of lombok.ast.grammar.PerformanceTest

/*
* Copyright (C) 2010 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package lombok.ast.grammar;

import static org.junit.Assert.fail;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Collection;
import java.util.List;

import lombok.Cleanup;
import lombok.ast.grammar.RunForEachFileInDirRunner.DirDescriptor;

import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.parboiled.Parboiled;
import org.parboiled.ReportingParseRunner;

import com.google.common.collect.Lists;
import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.util.Context;

@RunWith(RunForEachFileInDirRunner.class)
public class PerformanceTest extends RunForEachFileInDirRunner.SourceFileBasedTester {
  private static final int REPS = 50;
  private static final boolean VERBOSE = System.getProperty("lombok.ast.test.verbose") != null;
  private static final boolean EXTENDED = System.getProperty("lombok.ast.test.extended") != null;
  private static final double MAX_FACTOR = 15;
  private static long javacTotal, lombokTotal, ecjTotal, parboiledTotal;
 
  @BeforeClass
  public void init() {
    if (VERBOSE) {
      System.out.printf("[%20s / %30s] Per entry: time in millis for %d reps [lombok takes X longer than ~ : ~ takes X longer than javac]\n",
          "path", "file", REPS);
    }
  }
 
  @AfterClass
  public void summary() {
    if (VERBOSE) {
      System.out.printf("[%20s / %30s] l.ast: %5d [  1.00 : %6.02f] jc: %5d [%6.02f :   1.00] ecj: %5d [%6.02f : %6.02f] pb: %5d [%6.02f : %6.02f]\n",
          "", "*** TOTALS ***",
          lombokTotal, (double)lombokTotal / javacTotal,
          javacTotal, (double)lombokTotal / javacTotal,
          ecjTotal, (double)lombokTotal / ecjTotal, (double)ecjTotal / javacTotal,
          parboiledTotal, (double)lombokTotal / parboiledTotal, (double)parboiledTotal / javacTotal);
    }
  }
 
  @Override protected Collection<DirDescriptor> getDirDescriptors() {
    List<DirDescriptor> descriptors = Lists.newArrayList();
    descriptors.add(DirDescriptor.of(new File("test/resources/idempotency"), true));
    descriptors.add(DirDescriptor.of(new File("test/resources/alias"), true));
    descriptors.add(DirDescriptor.of(new File("test/resources/special"), true));
    if (VERBOSE) {
      descriptors.add(DirDescriptor.of(new File("test/resources/performance"), true));
    }
    return descriptors;
  }
 
  @Test
  public boolean testPerformance(Source source) {
    if (!EXTENDED) return false;
    parseWithJavac(source);
    long takenByJavac = System.currentTimeMillis();
    for (int i = 0; i < REPS; i++) {
      parseWithJavac(source);
    }
    takenByJavac = System.currentTimeMillis() - takenByJavac;
    javacTotal += takenByJavac;
   
    parseWithEcj(source);
    long takenByEcj = System.currentTimeMillis();
    for (int i = 0; i < REPS; i++) {
      parseWithEcj(source);
    }
    takenByEcj = System.currentTimeMillis() - takenByEcj;
    ecjTotal += takenByEcj;
   
    source.parseCompilationUnit();
    long takenByLombok = System.currentTimeMillis();
    for (int i = 0; i < REPS; i++) {
      source.clear();
      source.parseCompilationUnit();
    }
    takenByLombok = System.currentTimeMillis() - takenByLombok;
    lombokTotal += takenByLombok;
   
    parseWithParboiled(source);
    long takenByParboiled = System.currentTimeMillis();
    for (int i = 0; i < REPS; i++) {
      parseWithParboiled(source);
    }
    takenByParboiled = System.currentTimeMillis() - takenByParboiled;
    parboiledTotal += takenByParboiled;
   
    String fn = source.getName();
    String fnPrefix, fnSuffix, fileName; {
      int sep = fn.lastIndexOf('/');
      if (sep == -1) {
        fnPrefix = "";
        fileName = fnSuffix = fn;
      } else {
        fnPrefix = fn.substring(0, sep);
        fileName = fnSuffix = fn.substring(sep + 1);
      }
      if (fnSuffix.endsWith(".java")) fnSuffix = fnSuffix.substring(0, fnSuffix.length() - ".java".length());
      if (fnPrefix.length() > 20) fnPrefix = "\u2026" + fnPrefix.substring(fnPrefix.length() - 19);
      if (fnSuffix.length() > 30) fnSuffix = fnSuffix.substring(0, 10) + "\u2026" + fnSuffix.substring(fnSuffix.length() - 19);
    }
   
    if (VERBOSE) {
      System.out.printf("[%20s / %30s] l.ast: %5d [  1.00 : %6.02f] jc: %5d [%6.02f :   1.00] ecj: %5d [%6.02f : %6.02f] pb: %5d [%6.02f : %6.02f]\n",
          fnPrefix, fnSuffix,
          takenByLombok, (double)takenByLombok / takenByJavac,
          takenByJavac, (double)takenByLombok / takenByJavac,
          takenByEcj, (double)takenByLombok / takenByEcj, (double)takenByEcj / takenByJavac,
          takenByParboiled, (double)takenByLombok / takenByParboiled, (double)takenByParboiled / takenByJavac);
    }
   
    double factorVsJavac = (double)takenByLombok / takenByJavac;
    if (factorVsJavac > MAX_FACTOR) {
      if (VERBOSE) {
        try {
          File reportFile = new File("test/reports/" + fileName + ".report");
          reportFile.getParentFile().mkdirs();
          @Cleanup FileOutputStream rawOut = new FileOutputStream(reportFile);
          Writer out = new BufferedWriter(new OutputStreamWriter(rawOut, "UTF-8"));
          out.write(String.format("Parse Profile for: %s which is slower than javac by a factor of %.02f\n", source.getName(), factorVsJavac));
          for (String report : source.getDetailedProfileInformation(25)) {
            out.write(report);
            out.write("===================================");
            out.write("\n");
          }
          out.close();
          rawOut.close();
          System.out.println("Profile report written to: " + reportFile.getCanonicalPath());
        } catch (IOException e) {
          System.err.println("I/O error writing profile report on " + source.getName() + "; Possibly ./test/reports is not writable?");
          e.printStackTrace();
        }
      }
      fail(String.format("Performance is slower than javac by factor %d on %s", (int)factorVsJavac, source.getName()));
    }
   
    return true;
  }
 
  private void parseWithParboiled(Source source) {
    if (VERBOSE) {
      ParboiledJavaGrammar parser = Parboiled.createParser(ParboiledJavaGrammar.class);
      ReportingParseRunner.run(parser.CompilationUnit(), source.getRawInput());
    }
  }
 
  private void parseWithJavac(Source source) {
    Context context = new Context();
    JavaCompiler compiler = new JavaCompiler(context);
    compiler.genEndPos = true;
    compiler.parse(new ContentBasedJavaFileObject(source.getName(), source.getRawInput()));
  }
 
  protected CompilerOptions ecjCompilerOptions() {
    CompilerOptions options = new CompilerOptions();
    options.complianceLevel = ClassFileConstants.JDK1_6;
    options.sourceLevel = ClassFileConstants.JDK1_6;
    options.targetJDK = ClassFileConstants.JDK1_6;
    options.parseLiteralExpressionsAsConstants = true;
    return options;
  }
 
  private void parseWithEcj(Source source) {
    if (VERBOSE) {
      CompilerOptions compilerOptions = ecjCompilerOptions();
      Parser parser = new Parser(new ProblemReporter(
          DefaultErrorHandlingPolicies.proceedWithAllProblems(),
          compilerOptions,
          new DefaultProblemFactory()
        ), compilerOptions.parseLiteralExpressionsAsConstants);
      parser.javadocParser.checkDocComment = true;
      CompilationUnit sourceUnit = new CompilationUnit(source.getRawInput().toCharArray(), source.getName(), "UTF-8");
      CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, 0);
      parser.parse(sourceUnit, compilationResult);
    }
  }
}
TOP

Related Classes of lombok.ast.grammar.PerformanceTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.