added antlr comparison test

This commit is contained in:
2018-09-09 21:45:58 +01:00
parent 1f7261bca8
commit 135c56151c
9 changed files with 245 additions and 36 deletions

View File

@@ -24,10 +24,14 @@ libraryDependencies += "org.projectlombok" % "lombok" % "1.18.2"
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test"
libraryDependencies += "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.6" % "test"
libraryDependencies += "org.antlr" % "antlr4" % "4.7.1" % "compile"
libraryDependencies += "org.antlr" % "antlr4" % "4.7.1" % "test"
libraryDependencies += "org.antlr" % "antlr4-runtime" % "4.7.1" % "test"
libraryDependencies += "org.tukaani" % "xz" % "1.8" % "test"
artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
artifact.name + "-" + module.revision + "." + artifact.extension
}
enablePlugins(Antlr4Plugin)
antlr4Version in Antlr4 := "4.7.1"
antlr4PackageName in Antlr4 := Some("org.oggio88.worth.antlr")

View File

@@ -7,3 +7,4 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.9.3")
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "4.1.0")
addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.3")
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.6")
addSbtPlugin("com.simplytyped" % "sbt-antlr4" % "0.8.1")

View File

@@ -27,17 +27,27 @@ value
| NUMBER
| obj
| array
| 'true'
| 'false'
| 'null'
| TRUE
| FALSE
| NULL
;
TRUE
: 'true'
;
FALSE
: 'false'
;
NULL
: 'null'
;
STRING
: '"' (ESC | SAFECODEPOINT)* '"'
;
fragment ESC
: '\\' (["\\/bfnrt] | UNICODE)
;

View File

@@ -0,0 +1,25 @@
package org.oggio88.worth.buffer;
import java.io.IOException;
import java.io.InputStream;
public class LookAheadInputStream extends InputStream {
private final InputStream stream;
private int currentByte;
LookAheadInputStream(InputStream stream) {
this.stream = stream;
}
@Override
public int read() throws IOException {
int result = currentByte;
currentByte = stream.read();
return result;
}
public int getCurrentByte(){
return currentByte;
}
}

View File

@@ -23,6 +23,37 @@ public class JSONDumper extends ValueDumper {
protected Writer writer;
private String escapeString(String value){
StringBuilder sb = new StringBuilder();
for (char c : value.toCharArray()) {
switch (c) {
case '"':
sb.append("\\\"");
break;
case '\r':
sb.append("\\r");
break;
case '\n':
sb.append("\\n");
break;
case '\t':
sb.append("\\t");
break;
case '\\':
sb.append("\\\\");
break;
default: {
if (c < 128)
sb.append(c);
else {
sb.append("\\u").append(String.format("%04X", (int) c));
}
}
}
}
return sb.toString();
}
@Override
public void dump(Value value, OutputStream stream) {
dump(value, new OutputStreamWriter(stream));
@@ -121,40 +152,13 @@ public class JSONDumper extends ValueDumper {
@Override
@SneakyThrows
protected void objectKey(String key) {
this.writer.write("\"" + key + "\"");
this.writer.write("\"" + escapeString(key) + "\"");
}
@Override
@SneakyThrows
protected void stringValue(String value) {
StringBuilder sb = new StringBuilder();
for (char c : value.toCharArray()) {
switch (c) {
case '"':
sb.append("\\\"");
break;
case '\r':
sb.append("\\r");
break;
case '\n':
sb.append("\\n");
break;
case '\t':
sb.append("\\t");
break;
case '\\':
sb.append("\\\\");
break;
default: {
if (c < 128)
sb.append(c);
else {
sb.append("\\u").append(String.format("%04X", (int) c));
}
}
}
}
this.writer.write("\"" + sb.toString() + "\"");
this.writer.write("\"" + escapeString(value) + "\"");
}
@Override

View File

@@ -1,7 +1,10 @@
package org.oggio88.worth.utils;
import lombok.SneakyThrows;
import org.oggio88.worth.buffer.CircularBuffer;
import org.oggio88.worth.exception.ParseException;
import java.io.InputStream;
import java.util.concurrent.Callable;
public class WorthUtils {

View File

@@ -0,0 +1,102 @@
package org.oggio88.worth.antlr;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.oggio88.worth.serialization.ValueParser;
import org.oggio88.worth.xface.Value;
public class JSONListenerImpl extends ValueParser implements JSONListener {
public Value result = null;
private String unquote(String quoted) {
return quoted.substring(1, quoted.length() - 1);
}
@Override
public void enterJson(JSONParser.JsonContext ctx) {
}
@Override
public void exitJson(JSONParser.JsonContext ctx) {
result = stack.get(0).value;
stack.clear();
}
@Override
public void enterObj(JSONParser.ObjContext ctx) {
beginObject();
}
@Override
public void exitObj(JSONParser.ObjContext ctx) {
endObject();
}
@Override
public void enterPair(JSONParser.PairContext ctx) {
objectKey(unquote(ctx.STRING().getText()));
}
@Override
public void exitPair(JSONParser.PairContext ctx) {
}
@Override
public void enterArray(JSONParser.ArrayContext ctx) {
beginArray();
}
@Override
public void exitArray(JSONParser.ArrayContext ctx) {
endArray();
}
@Override
public void enterValue(JSONParser.ValueContext ctx) {
if (ctx.obj() != null) {
} else if (ctx.array() != null) {
} else if (ctx.STRING() != null) {
stringValue(unquote(ctx.STRING().getText()));
} else if (ctx.TRUE() != null) {
booleanValue(true);
} else if (ctx.FALSE() != null) {
booleanValue(false);
} else if (ctx.NULL() != null) {
nullValue();
} else if (ctx.NUMBER() != null) {
String text = ctx.NUMBER().getText();
if (text.indexOf('.') < 0)
integerValue(Long.valueOf(text));
else
floatValue(Float.valueOf(text));
}
}
@Override
public void exitValue(JSONParser.ValueContext ctx) {
}
@Override
public void visitTerminal(TerminalNode node) {
}
@Override
public void visitErrorNode(ErrorNode node) {
}
@Override
public void enterEveryRule(ParserRuleContext ctx) {
}
@Override
public void exitEveryRule(ParserRuleContext ctx) {
}
}

View File

@@ -0,0 +1,28 @@
package org.oggio88.worth.antlr;
import lombok.SneakyThrows;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.junit.Test;
import org.oggio88.worth.serialization.json.JSONDumper;
import org.oggio88.worth.xface.Value;
public class ParseTest {
@Test
@SneakyThrows
public void test(){
ANTLRInputStream inputStream = new ANTLRInputStream(getClass().getResourceAsStream("/test.json"));
JSONLexer lexer = new JSONLexer(inputStream);
CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
JSONParser parser = new JSONParser(commonTokenStream);
JSONListenerImpl listener = new JSONListenerImpl();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(listener, parser.json());
Value result = listener.result;
new JSONDumper().dump(result, System.out);
// TestRig.main(new String[] {"org.oggio88.worth.antlr.JSON", "json", "-ps", "tree.ps", "src/test/resources/test.json"});
}
}

View File

@@ -3,8 +3,13 @@ package org.oggio88.worth.serialization.json;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.junit.Ignore;
import org.junit.Test;
import org.oggio88.worth.antlr.JSONLexer;
import org.oggio88.worth.antlr.JSONListenerImpl;
import org.oggio88.worth.xface.Value;
import org.tukaani.xz.XZInputStream;
@@ -65,7 +70,7 @@ public class PerformanceTest {
@Test
@SneakyThrows
public void loopTest() {
double jacksonTime, worthTime;
double jacksonTime, worthTime, antlrTime;
final int loops = 100;
Chronometer chr = new Chronometer();
{
@@ -85,6 +90,21 @@ public class PerformanceTest {
worthTime = chr.stop(Chronometer.TimeUnit.MILLISECOND);
System.out.printf("Worth time: %8s msec\n", String.format("%.3f", worthTime));
}
{
chr.reset();
for (int i = 0; i < loops; i++) {
ANTLRInputStream inputStream = new ANTLRInputStream(
getClass().getResourceAsStream("/wordpress.json"));
JSONLexer lexer = new JSONLexer(inputStream);
CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
org.oggio88.worth.antlr.JSONParser parser = new org.oggio88.worth.antlr.JSONParser(commonTokenStream);
JSONListenerImpl listener = new JSONListenerImpl();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(listener, parser.json());
}
antlrTime = chr.stop(Chronometer.TimeUnit.MILLISECOND);
System.out.printf("Antlr time: %8s msec\n", String.format("%.3f", antlrTime));
}
}
@Test
@@ -92,7 +112,7 @@ public class PerformanceTest {
@SneakyThrows
public void hugeJSONTest() {
byte[] testData = extractTestData();
double jacksonTime, worthTime;
double jacksonTime, worthTime, antlrTime;
Chronometer chr = new Chronometer();
{
chr.reset();
@@ -107,5 +127,17 @@ public class PerformanceTest {
worthTime = chr.stop(Chronometer.TimeUnit.SECOND);
System.out.printf("Worth time: %8s sec\n", String.format("%.3f", worthTime));
}
{
chr.reset();
ANTLRInputStream inputStream = new ANTLRInputStream(new ByteArrayInputStream(testData));
JSONLexer lexer = new JSONLexer(inputStream);
CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
org.oggio88.worth.antlr.JSONParser parser = new org.oggio88.worth.antlr.JSONParser(commonTokenStream);
JSONListenerImpl listener = new JSONListenerImpl();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(listener, parser.json());
antlrTime = chr.stop(Chronometer.TimeUnit.SECOND);
System.out.printf("Antlr time: %8s sec\n", String.format("%.3f", antlrTime));
}
}
}