summaryrefslogtreecommitdiffstats
path: root/benchmarks/regression/ParseBenchmark.java
diff options
context:
space:
mode:
Diffstat (limited to 'benchmarks/regression/ParseBenchmark.java')
-rw-r--r--benchmarks/regression/ParseBenchmark.java217
1 files changed, 217 insertions, 0 deletions
diff --git a/benchmarks/regression/ParseBenchmark.java b/benchmarks/regression/ParseBenchmark.java
new file mode 100644
index 0000000..b44b429
--- /dev/null
+++ b/benchmarks/regression/ParseBenchmark.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks.regression;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParserFactory;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Measure throughput of various parsers.
+ *
+ * <p>This benchmark requires that ParseBenchmarkData.zip is on the classpath.
+ * That file contains Twitter feed data, which is representative of what
+ * applications will be parsing.
+ */
+public final class ParseBenchmark extends SimpleBenchmark {
+
+ @Param Document document;
+ @Param Api api;
+
+ private enum Document {
+ TWEETS,
+ READER_SHORT,
+ READER_LONG
+ }
+
+ private enum Api {
+ ANDROID_STREAM("json") {
+ @Override Parser newParser() {
+ return new AndroidStreamParser();
+ }
+ },
+ ORG_JSON("json") {
+ @Override Parser newParser() {
+ return new OrgJsonParser();
+ }
+ },
+ XML_PULL("xml") {
+ @Override Parser newParser() {
+ return new GeneralXmlPullParser();
+ }
+ },
+ XML_DOM("xml") {
+ @Override Parser newParser() {
+ return new XmlDomParser();
+ }
+ },
+ XML_SAX("xml") {
+ @Override Parser newParser() {
+ return new XmlSaxParser();
+ }
+ };
+
+ final String extension;
+
+ private Api(String extension) {
+ this.extension = extension;
+ }
+
+ abstract Parser newParser();
+ }
+
+ private String text;
+ private Parser parser;
+
+ @Override protected void setUp() throws Exception {
+ text = resourceToString("/" + document.name() + "." + api.extension);
+ parser = api.newParser();
+ }
+
+ public void timeParse(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ parser.parse(text);
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ Runner.main(ParseBenchmark.class, args);
+ }
+
+ private static String resourceToString(String path) throws Exception {
+ InputStream in = ParseBenchmark.class.getResourceAsStream(path);
+ if (in == null) {
+ throw new IllegalArgumentException("No such file: " + path);
+ }
+
+ Reader reader = new InputStreamReader(in, "UTF-8");
+ char[] buffer = new char[8192];
+ StringWriter writer = new StringWriter();
+ int count;
+ while ((count = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, count);
+ }
+ reader.close();
+ return writer.toString();
+ }
+
+ interface Parser {
+ void parse(String data) throws Exception;
+ }
+
+ private static class AndroidStreamParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ android.util.JsonReader jsonReader
+ = new android.util.JsonReader(new StringReader(data));
+ readToken(jsonReader);
+ jsonReader.close();
+ }
+
+ public void readObject(android.util.JsonReader reader) throws IOException {
+ reader.beginObject();
+ while (reader.hasNext()) {
+ reader.nextName();
+ readToken(reader);
+ }
+ reader.endObject();
+ }
+
+ public void readArray(android.util.JsonReader reader) throws IOException {
+ reader.beginArray();
+ while (reader.hasNext()) {
+ readToken(reader);
+ }
+ reader.endArray();
+ }
+
+ private void readToken(android.util.JsonReader reader) throws IOException {
+ switch (reader.peek()) {
+ case BEGIN_ARRAY:
+ readArray(reader);
+ break;
+ case BEGIN_OBJECT:
+ readObject(reader);
+ break;
+ case BOOLEAN:
+ reader.nextBoolean();
+ break;
+ case NULL:
+ reader.nextNull();
+ break;
+ case NUMBER:
+ reader.nextLong();
+ break;
+ case STRING:
+ reader.nextString();
+ break;
+ default:
+ throw new IllegalArgumentException("Unexpected token" + reader.peek());
+ }
+ }
+ }
+
+ private static class OrgJsonParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ if (data.startsWith("[")) {
+ new JSONArray(data);
+ } else if (data.startsWith("{")) {
+ new JSONObject(data);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ private static class GeneralXmlPullParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ XmlPullParser xmlParser = android.util.Xml.newPullParser();
+ xmlParser.setInput(new StringReader(data));
+ xmlParser.nextTag();
+ while (xmlParser.next() != XmlPullParser.END_DOCUMENT) {
+ xmlParser.getName();
+ xmlParser.getText();
+ }
+ }
+ }
+
+ private static class XmlDomParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ DocumentBuilderFactory.newInstance().newDocumentBuilder()
+ .parse(new InputSource(new StringReader(data)));
+ }
+ }
+
+ private static class XmlSaxParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ SAXParserFactory.newInstance().newSAXParser().parse(
+ new InputSource(new StringReader(data)), new DefaultHandler());
+ }
+ }
+}