diff --git a/src/main/antlr4/JSON.g4 b/antlr/src/main/antlr4/JSON.g4 similarity index 100% rename from src/main/antlr4/JSON.g4 rename to antlr/src/main/antlr4/JSON.g4 diff --git a/src/test/java/net/woggioni/worth/antlr/JSONListenerImpl.java b/antlr/src/main/java/net/woggioni/worth/antlr/JSONListenerImpl.java similarity index 100% rename from src/test/java/net/woggioni/worth/antlr/JSONListenerImpl.java rename to antlr/src/main/java/net/woggioni/worth/antlr/JSONListenerImpl.java diff --git a/src/test/java/net/woggioni/worth/antlr/ParseTest.java b/antlr/src/test/java/net/woggioni/worth/antlr/ParseTest.java similarity index 58% rename from src/test/java/net/woggioni/worth/antlr/ParseTest.java rename to antlr/src/test/java/net/woggioni/worth/antlr/ParseTest.java index c5a1013..b558c9e 100644 --- a/src/test/java/net/woggioni/worth/antlr/ParseTest.java +++ b/antlr/src/test/java/net/woggioni/worth/antlr/ParseTest.java @@ -1,8 +1,10 @@ package net.woggioni.worth.antlr; import lombok.SneakyThrows; +import net.woggioni.worth.serialization.JsonBombTest; import net.woggioni.worth.serialization.json.JSONDumper; import net.woggioni.worth.xface.Value; +import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CodePointCharStream; import org.antlr.v4.runtime.CommonTokenStream; @@ -11,12 +13,13 @@ import org.junit.Test; import java.io.InputStreamReader; +import static net.woggioni.worth.serialization.JsonBombTest.infiniteJson; + public class ParseTest { @Test @SneakyThrows public void test(){ - CodePointCharStream inputStream = CharStreams.fromReader(new InputStreamReader(getClass().getResourceAsStream("/test.json"))); JSONLexer lexer = new JSONLexer(inputStream); CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); @@ -27,4 +30,16 @@ public class ParseTest { Value result = listener.result; new JSONDumper().dump(result, System.out); } + + @Test(expected = OutOfMemoryError.class) + @SneakyThrows + public void antlr() { + CharStream inputStream = CharStreams.fromReader(new InputStreamReader(infiniteJson())); + JSONLexer lexer = new JSONLexer(inputStream); + CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); + net.woggioni.worth.antlr.JSONParser parser = new net.woggioni.worth.antlr.JSONParser(commonTokenStream); + JSONListenerImpl listener = new JSONListenerImpl(); + ParseTreeWalker walker = new ParseTreeWalker(); + walker.walk(listener, parser.json()); + } } diff --git a/antlr/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java b/antlr/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java new file mode 100644 index 0000000..79bf70b --- /dev/null +++ b/antlr/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java @@ -0,0 +1,143 @@ +package net.woggioni.worth.serialization.json; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; +import net.woggioni.worth.antlr.JSONLexer; +import net.woggioni.worth.antlr.JSONListenerImpl; +import net.woggioni.worth.serialization.binary.JBONDumper; +import net.woggioni.worth.xface.Dumper; +import net.woggioni.worth.xface.Parser; +import net.woggioni.worth.xface.Value; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTreeWalker; +import org.junit.Ignore; +import org.junit.Test; +import org.tukaani.xz.XZInputStream; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; + +public class PerformanceTest { + + @SneakyThrows + private static InputStream extractTestData() { + return new XZInputStream(new BufferedInputStream(PerformanceTest.class.getResourceAsStream("/citylots.json.xz"))); + } + + private static InputStream smallTestData() { + return new BufferedInputStream(PerformanceTest.class.getResourceAsStream("/wordpress.json")); + } + + @Test + @Ignore + @SneakyThrows + public void profilerTest() { + while (true) { + Value value = new JSONParser().parse(getClass().getResourceAsStream("/wordpress.json")); + } + } + + @Test + @SneakyThrows + public void loopTest() { + double jacksonTime, worthTime, antlrTime; + final int loops = 100; + Chronometer chr = new Chronometer(); + { + ObjectMapper om = new ObjectMapper(); + for(int j = 0; j < 2; j++) { + chr.reset(); + for (int i = 0; i < loops; i++) { + JsonNode jsonNode = om.readTree(smallTestData()); + } + } + jacksonTime = chr.stop(Chronometer.TimeUnit.MILLISECOND); + System.out.printf("Jackson time: %8s msec\n", String.format("%.3f", jacksonTime)); + } + { + for(int j = 0; j < 2; j++) { + chr.reset(); + for(int i = 0; i < loops; i++) { + Value value = new JSONParser().parse(smallTestData()); + } + } + worthTime = chr.stop(Chronometer.TimeUnit.MILLISECOND); + System.out.printf("Worth time: %8s msec\n", String.format("%.3f", worthTime)); + } + { + for(int j = 0; j < 2; j++) { + chr.reset(); + for(int i = 0; i < loops; i++) { + CharStream inputStream = CharStreams.fromReader(new InputStreamReader(smallTestData())); + JSONLexer lexer = new JSONLexer(inputStream); + CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); + net.woggioni.worth.antlr.JSONParser parser = new net.woggioni.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 + @Ignore + @SneakyThrows + public void hugeJSONTest() { + double jacksonTime, worthTime, antlrTime; + Chronometer chr = new Chronometer(); + try(InputStream is = extractTestData()) { + chr.reset(); + ObjectMapper om = new ObjectMapper(); + om.readTree(is); + jacksonTime = chr.stop(Chronometer.TimeUnit.SECOND); + System.out.printf("Jackson time: %8s sec\n", String.format("%.3f", jacksonTime)); + } + try(InputStream is = extractTestData()) { + chr.reset(); + new JSONParser().parse(is); + worthTime = chr.stop(Chronometer.TimeUnit.SECOND); + System.out.printf("Worth time: %8s sec\n", String.format("%.3f", worthTime)); + } + try(InputStream is = extractTestData()) { + chr.reset(); + CharStream inputStream = CharStreams.fromReader(new InputStreamReader(is)); + JSONLexer lexer = new JSONLexer(inputStream); + CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); + net.woggioni.worth.antlr.JSONParser parser = new net.woggioni.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)); + } + } + + @Test + @Ignore + @SneakyThrows + public void tess() { + Value value; + try(InputStream is = extractTestData()) { + Parser parser = JSONParser.newInstance(); + value = parser.parse(is); + } + try(OutputStream os = new BufferedOutputStream(new FileOutputStream("/tmp/citylots.json"))) { + Dumper dumper = JSONDumper.newInstance(); + dumper.dump(value, os); + } + try(OutputStream os = new BufferedOutputStream(new FileOutputStream("/tmp/citylots.jbon"))) { + Dumper dumper = JBONDumper.newInstance(); + dumper.dump(value, os); + } + } +} diff --git a/build.sbt b/build.sbt index d4ba1e3..225d356 100644 --- a/build.sbt +++ b/build.sbt @@ -19,15 +19,27 @@ fork := true //javaOptions in Test += "-Xmx14G" //scalafmtOnCompile := true libraryDependencies += "org.projectlombok" % "lombok" % "1.18.8" -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" % Test -libraryDependencies += "org.antlr" % "antlr4-runtime" % "4.7.1" % Test -libraryDependencies += "org.tukaani" % "xz" % "1.8" % Test +val testDependencies = Seq("com.novocode" % "junit-interface" % "0.11" % Test, + "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.6" % Test, + "org.tukaani" % "xz" % "1.8" % Test) +libraryDependencies ++= testDependencies +testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-a") -enablePlugins(Antlr4Plugin) -antlr4Version in Antlr4 := "4.7.1" -antlr4PackageName in Antlr4 := Some("net.woggioni.worth.antlr") - -testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-a") \ No newline at end of file +val antlrVersion = "4.7.2" +lazy val worthAntlr = (project in file("antlr")).settings( + organization := (organization in LocalRootProject).value, + name := "worth-antlr", + version := (version in LocalRootProject).value, +// mainClass := Some("com.jlevtree.benchmark.Benchmark"), +// mappings in packageBin in Compile ++= (mappings in(LocalRootProject, Compile, packageBin)).value, + resourceDirectory := (resourceDirectory in(LocalRootProject, Test)).value, + antlr4Version in Antlr4 := antlrVersion, + antlr4PackageName in Antlr4 := Some("net.woggioni.worth.antlr"), + skip in publish := true, + unmanagedClasspath in Test += (classDirectory in (LocalRootProject, Test)).value, + libraryDependencies += "org.antlr" % "antlr4" % antlrVersion % Compile, + libraryDependencies += "org.antlr" % "antlr4-runtime" % antlrVersion, + libraryDependencies += "org.projectlombok" % "lombok" % "1.18.8", + libraryDependencies ++= testDependencies +).dependsOn(LocalRootProject).enablePlugins(Antlr4Plugin) diff --git a/src/test/java/net/woggioni/worth/serialization/JsonBombTest.java b/src/test/java/net/woggioni/worth/serialization/JsonBombTest.java index 929598d..24daa41 100644 --- a/src/test/java/net/woggioni/worth/serialization/JsonBombTest.java +++ b/src/test/java/net/woggioni/worth/serialization/JsonBombTest.java @@ -2,24 +2,17 @@ package net.woggioni.worth.serialization; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; -import net.woggioni.worth.antlr.JSONLexer; -import net.woggioni.worth.antlr.JSONListenerImpl; import net.woggioni.worth.exception.MaxDepthExceededException; import net.woggioni.worth.serialization.json.JSONParser; import net.woggioni.worth.xface.Parser; import net.woggioni.worth.xface.Value; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.junit.Test; import java.io.InputStream; -import java.io.InputStreamReader; public class JsonBombTest { - private InputStream infiniteJson() { + public static InputStream infiniteJson() { return new InputStream() { int index = 0; final String monomer = "{\"key\":["; @@ -44,16 +37,4 @@ public class JsonBombTest { Parser parser = JSONParser.newInstance(cfg); parser.parse(infiniteJson()); } - - @Test(expected = OutOfMemoryError.class) - @SneakyThrows - public void antlr() { - CharStream inputStream = CharStreams.fromReader(new InputStreamReader(infiniteJson())); - JSONLexer lexer = new JSONLexer(inputStream); - CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); - net.woggioni.worth.antlr.JSONParser parser = new net.woggioni.worth.antlr.JSONParser(commonTokenStream); - JSONListenerImpl listener = new JSONListenerImpl(); - ParseTreeWalker walker = new ParseTreeWalker(); - walker.walk(listener, parser.json()); - } } diff --git a/src/test/java/net/woggioni/worth/serialization/ReferenceTest.java b/src/test/java/net/woggioni/worth/serialization/ReferenceTest.java index fd22d0f..de70c97 100644 --- a/src/test/java/net/woggioni/worth/serialization/ReferenceTest.java +++ b/src/test/java/net/woggioni/worth/serialization/ReferenceTest.java @@ -59,4 +59,13 @@ public class ReferenceTest { public void jbon() { common(JBONDumper::new, JBONParser::new); } + + @Test + public void test() { + Value.Configuration cfg = Value.Configuration.builder().serializeReferences(true).build(); + Value root = ObjectValue.newInstance(cfg); + root.put("child1", root); + root.put("child2", ObjectValue.newInstance(cfg)); + new JSONDumper(cfg).dump(root, System.out); + } } diff --git a/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java b/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java index 6699dbf..0a0b266 100644 --- a/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java +++ b/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java @@ -1,24 +1,5 @@ package net.woggioni.worth.serialization.json; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.SneakyThrows; -import net.woggioni.worth.antlr.JSONLexer; -import net.woggioni.worth.antlr.JSONListenerImpl; -import net.woggioni.worth.serialization.binary.JBONDumper; -import net.woggioni.worth.xface.Dumper; -import net.woggioni.worth.xface.Parser; -import net.woggioni.worth.xface.Value; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.tree.ParseTreeWalker; -import org.junit.Ignore; -import org.junit.Test; -import org.tukaani.xz.XZInputStream; - -import java.io.*; - class Chronometer { public enum TimeUnit { @@ -51,120 +32,3 @@ class Chronometer { } -public class PerformanceTest { - - @SneakyThrows - private static InputStream extractTestData() { - return new XZInputStream(new BufferedInputStream(PerformanceTest.class.getResourceAsStream("/citylots.json.xz"))); - } - - private static InputStream smallTestData() { - return new BufferedInputStream(PerformanceTest.class.getResourceAsStream("/wordpress.json")); - } - - @Test - @Ignore - @SneakyThrows - public void profilerTest() { - while (true) { - Value value = new JSONParser().parse(getClass().getResourceAsStream("/wordpress.json")); - } - } - - @Test - @SneakyThrows - public void loopTest() { - double jacksonTime, worthTime, antlrTime; - final int loops = 100; - Chronometer chr = new Chronometer(); - { - ObjectMapper om = new ObjectMapper(); - for(int j = 0; j < 2; j++) { - chr.reset(); - for (int i = 0; i < loops; i++) { - JsonNode jsonNode = om.readTree(smallTestData()); - } - } - jacksonTime = chr.stop(Chronometer.TimeUnit.MILLISECOND); - System.out.printf("Jackson time: %8s msec\n", String.format("%.3f", jacksonTime)); - } - { - for(int j = 0; j < 2; j++) { - chr.reset(); - for(int i = 0; i < loops; i++) { - Value value = new JSONParser().parse(smallTestData()); - } - } - worthTime = chr.stop(Chronometer.TimeUnit.MILLISECOND); - System.out.printf("Worth time: %8s msec\n", String.format("%.3f", worthTime)); - } - { - for(int j = 0; j < 2; j++) { - chr.reset(); - for(int i = 0; i < loops; i++) { - CharStream inputStream = CharStreams.fromReader(new InputStreamReader(smallTestData())); - JSONLexer lexer = new JSONLexer(inputStream); - CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); - net.woggioni.worth.antlr.JSONParser parser = new net.woggioni.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 - @Ignore - @SneakyThrows - public void hugeJSONTest() { - double jacksonTime, worthTime, antlrTime; - Chronometer chr = new Chronometer(); - try(InputStream is = extractTestData()) { - chr.reset(); - ObjectMapper om = new ObjectMapper(); - om.readTree(is); - jacksonTime = chr.stop(Chronometer.TimeUnit.SECOND); - System.out.printf("Jackson time: %8s sec\n", String.format("%.3f", jacksonTime)); - } - try(InputStream is = extractTestData()) { - chr.reset(); - new JSONParser().parse(is); - worthTime = chr.stop(Chronometer.TimeUnit.SECOND); - System.out.printf("Worth time: %8s sec\n", String.format("%.3f", worthTime)); - } - try(InputStream is = extractTestData()) { - chr.reset(); - CharStream inputStream = CharStreams.fromReader(new InputStreamReader(is)); - JSONLexer lexer = new JSONLexer(inputStream); - CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); - net.woggioni.worth.antlr.JSONParser parser = new net.woggioni.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)); - } - } - - @Test - @Ignore - @SneakyThrows - public void tess() { - Value value; - try(InputStream is = extractTestData()) { - Parser parser = JSONParser.newInstance(); - value = parser.parse(is); - } - try(OutputStream os = new BufferedOutputStream(new FileOutputStream("/tmp/citylots.json"))) { - Dumper dumper = JSONDumper.newInstance(); - dumper.dump(value, os); - } - try(OutputStream os = new BufferedOutputStream(new FileOutputStream("/tmp/citylots.jbon"))) { - Dumper dumper = JBONDumper.newInstance(); - dumper.dump(value, os); - } - } -}