Вывод информации о длительности работы парсера

This commit is contained in:
Victor 2016-02-19 11:42:29 +02:00
parent 2783417d4b
commit 3e16e49ce7
2 changed files with 100 additions and 6 deletions

View File

@ -1,8 +1,6 @@
package com.annimon.ownlang; package com.annimon.ownlang;
import com.annimon.ownlang.lib.CallStack; import com.annimon.ownlang.lib.CallStack;
import com.annimon.ownlang.lib.Function;
import com.annimon.ownlang.lib.Functions;
import com.annimon.ownlang.parser.Lexer; import com.annimon.ownlang.parser.Lexer;
import com.annimon.ownlang.parser.Parser; import com.annimon.ownlang.parser.Parser;
import com.annimon.ownlang.parser.Token; import com.annimon.ownlang.parser.Token;
@ -14,6 +12,7 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
/** /**
* @author aNNiMON * @author aNNiMON
@ -22,11 +21,11 @@ public final class Main {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
if (args.length == 0) { if (args.length == 0) {
run(readFile("program.own"), true, true); run(readFile("program.own"), true, true, true);
return; return;
} }
boolean showTokens = false, showAst = false; boolean showTokens = false, showAst = false, showMeasurements = false;
String input = null; String input = null;
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
switch (args[i]) { switch (args[i]) {
@ -40,6 +39,11 @@ public final class Main {
showTokens = true; showTokens = true;
break; break;
case "-m":
case "--showtime":
showMeasurements = true;
break;
case "-f": case "-f":
case "--file": case "--file":
if (i + 1 < args.length) { if (i + 1 < args.length) {
@ -55,23 +59,28 @@ public final class Main {
if (input == null) { if (input == null) {
throw new IllegalArgumentException("Empty input"); throw new IllegalArgumentException("Empty input");
} }
run(input, showTokens, showAst); run(input, showTokens, showAst, showMeasurements);
} }
private static String readFile(String file) throws IOException { private static String readFile(String file) throws IOException {
return new String( Files.readAllBytes(Paths.get(file)), "UTF-8"); return new String( Files.readAllBytes(Paths.get(file)), "UTF-8");
} }
private static void run(String input, boolean showTokens, boolean showAst) { private static void run(String input, boolean showTokens, boolean showAst, boolean showMeasurements) {
final TimeMeasurement measurement = new TimeMeasurement();
measurement.start("Tokenize time");
final List<Token> tokens = new Lexer(input).tokenize(); final List<Token> tokens = new Lexer(input).tokenize();
measurement.stop("Tokenize time");
if (showTokens) { if (showTokens) {
for (int i = 0; i < tokens.size(); i++) { for (int i = 0; i < tokens.size(); i++) {
System.out.println(i + " " + tokens.get(i)); System.out.println(i + " " + tokens.get(i));
} }
} }
measurement.start("Parse time");
final Parser parser = new Parser(tokens); final Parser parser = new Parser(tokens);
final Statement program = parser.parse(); final Statement program = parser.parse();
measurement.stop("Parse time");
if (showAst) { if (showAst) {
System.out.println(program.toString()); System.out.println(program.toString());
} }
@ -83,9 +92,15 @@ public final class Main {
// program.accept(new VariablePrinter()); // program.accept(new VariablePrinter());
program.accept(new AssignValidator()); program.accept(new AssignValidator());
try { try {
measurement.start("Execution time");
program.execute(); program.execute();
} catch (Exception ex) { } catch (Exception ex) {
handleException(Thread.currentThread(), ex); handleException(Thread.currentThread(), ex);
} finally {
if (showMeasurements) {
measurement.stop("Execution time");
System.out.println(measurement.summary(TimeUnit.MILLISECONDS, true));
}
} }
} }

View File

@ -0,0 +1,79 @@
package com.annimon.ownlang;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public final class TimeMeasurement {
private final Map<String, Long> finished, running;
public TimeMeasurement() {
finished = new HashMap<>();
running = new HashMap<>();
}
public void clear() {
finished.clear();
running.clear();
}
public void start(String... names) {
final long time = System.nanoTime();
for (String name : names) {
running.put(name, time);
}
}
public void pause(String... names) {
final long time = System.nanoTime();
for (String name : names) {
if (running.containsKey(name)) {
addTime(name, time - running.get(name));
running.remove(name);
}
}
}
public void stop(String... names) {
final long time = System.nanoTime();
for (String name : names) {
if (running.containsKey(name)) {
addTime(name, time - running.get(name));
}
}
}
public Map<String, Long> getFinished() {
return finished;
}
public String summary() {
return summary(TimeUnit.SECONDS, true);
}
public String summary(TimeUnit unit, boolean showSummary) {
final String unitName = unit.name().toLowerCase();
final StringBuilder result = new StringBuilder();
long summaryTime = 0;
for (Map.Entry<String, Long> entry : finished.entrySet()) {
final long convertedTime = unit.convert(entry.getValue(), TimeUnit.NANOSECONDS);
summaryTime += convertedTime;
result.append(entry.getKey()).append(": ")
.append(convertedTime).append(' ').append(unitName)
.append(System.lineSeparator());
}
if (showSummary) {
result.append("Summary: ")
.append(summaryTime).append(' ').append(unitName)
.append(System.lineSeparator());
}
return result.toString();
}
private void addTime(String name, long time) {
final long alreadyElapsed = finished.getOrDefault(name, 0L);
finished.put(name, alreadyElapsed + time);
}
}