From 3e16e49ce7e9fd78a9449a7df428bb47cbf6e34a Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 19 Feb 2016 11:42:29 +0200 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=8B=D0=B2=D0=BE=D0=B4=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8=20=D0=BE=20?= =?UTF-8?q?=D0=B4=D0=BB=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D0=BF?= =?UTF-8?q?=D0=B0=D1=80=D1=81=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/annimon/ownlang/Main.java | 27 +++++-- src/com/annimon/ownlang/TimeMeasurement.java | 79 ++++++++++++++++++++ 2 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/com/annimon/ownlang/TimeMeasurement.java diff --git a/src/com/annimon/ownlang/Main.java b/src/com/annimon/ownlang/Main.java index 390341d..1da24f5 100644 --- a/src/com/annimon/ownlang/Main.java +++ b/src/com/annimon/ownlang/Main.java @@ -1,8 +1,6 @@ package com.annimon.ownlang; 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.Parser; import com.annimon.ownlang.parser.Token; @@ -14,6 +12,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; +import java.util.concurrent.TimeUnit; /** * @author aNNiMON @@ -22,11 +21,11 @@ public final class Main { public static void main(String[] args) throws IOException { if (args.length == 0) { - run(readFile("program.own"), true, true); + run(readFile("program.own"), true, true, true); return; } - boolean showTokens = false, showAst = false; + boolean showTokens = false, showAst = false, showMeasurements = false; String input = null; for (int i = 0; i < args.length; i++) { switch (args[i]) { @@ -40,6 +39,11 @@ public final class Main { showTokens = true; break; + case "-m": + case "--showtime": + showMeasurements = true; + break; + case "-f": case "--file": if (i + 1 < args.length) { @@ -55,23 +59,28 @@ public final class Main { if (input == null) { throw new IllegalArgumentException("Empty input"); } - run(input, showTokens, showAst); + run(input, showTokens, showAst, showMeasurements); } private static String readFile(String file) throws IOException { 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 tokens = new Lexer(input).tokenize(); + measurement.stop("Tokenize time"); if (showTokens) { for (int i = 0; i < tokens.size(); i++) { System.out.println(i + " " + tokens.get(i)); } } + measurement.start("Parse time"); final Parser parser = new Parser(tokens); final Statement program = parser.parse(); + measurement.stop("Parse time"); if (showAst) { System.out.println(program.toString()); } @@ -83,9 +92,15 @@ public final class Main { // program.accept(new VariablePrinter()); program.accept(new AssignValidator()); try { + measurement.start("Execution time"); program.execute(); } catch (Exception ex) { handleException(Thread.currentThread(), ex); + } finally { + if (showMeasurements) { + measurement.stop("Execution time"); + System.out.println(measurement.summary(TimeUnit.MILLISECONDS, true)); + } } } diff --git a/src/com/annimon/ownlang/TimeMeasurement.java b/src/com/annimon/ownlang/TimeMeasurement.java new file mode 100644 index 0000000..0a7b5e4 --- /dev/null +++ b/src/com/annimon/ownlang/TimeMeasurement.java @@ -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 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 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 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); + } +}