197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes/* 297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * Copyright (C) 2010 Google Inc. 397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * 497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * you may not use this file except in compliance with the License. 697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * You may obtain a copy of the License at 797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * 897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * 1097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * Unless required by applicable law or agreed to in writing, software 1197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 1297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * See the License for the specific language governing permissions and 1497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * limitations under the License. 1597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes */ 1697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 1797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughespackage benchmarks; 1897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 1997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport com.google.caliper.Param; 2097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport com.google.caliper.Runner; 2197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport com.google.caliper.SimpleBenchmark; 2297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.io.ByteArrayInputStream; 2397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.io.ByteArrayOutputStream; 2497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.io.FileInputStream; 2597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.io.IOException; 2697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.lang.reflect.Constructor; 2797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.util.Arrays; 2897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.util.List; 2997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport javax.xml.parsers.DocumentBuilder; 3097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport javax.xml.parsers.DocumentBuilderFactory; 3197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport javax.xml.parsers.SAXParser; 3297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport javax.xml.parsers.SAXParserFactory; 3397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport org.w3c.dom.Document; 3497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport org.w3c.dom.Node; 3597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport org.xml.sax.Attributes; 3697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport org.xml.sax.SAXException; 3797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport org.xml.sax.helpers.DefaultHandler; 3897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport org.xmlpull.v1.XmlPullParser; 3997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 4097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughespublic class XmlParseBenchmark extends SimpleBenchmark { 4197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 4297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes @Param String xmlFile; 4397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes ByteArrayInputStream inputStream; 4497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 4597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes static List<String> xmlFileValues = Arrays.asList( 4697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes "/etc/apns-conf.xml", 4797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes "/etc/media_profiles.xml", 4897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes "/etc/permissions/features.xml" 4997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes ); 5097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 5197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private SAXParser saxParser; 5297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private DocumentBuilder documentBuilder; 5397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private Constructor<? extends XmlPullParser> kxmlConstructor; 5497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private Constructor<? extends XmlPullParser> expatConstructor; 5597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 5697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes @SuppressWarnings("unchecked") 5797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes @Override protected void setUp() throws Exception { 5897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes byte[] xmlBytes = getXmlBytes(); 5997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes inputStream = new ByteArrayInputStream(xmlBytes); 6097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes inputStream.mark(xmlBytes.length); 6197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 6297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); 6397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes saxParser = saxParserFactory.newSAXParser(); 6497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 6597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); 6697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes documentBuilder = builderFactory.newDocumentBuilder(); 6797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 6897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes kxmlConstructor = (Constructor) Class.forName("org.kxml2.io.KXmlParser").getConstructor(); 6997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes expatConstructor = (Constructor) Class.forName("org.apache.harmony.xml.ExpatPullParser") 7097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes .getConstructor(); 7197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 7297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 7397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private byte[] getXmlBytes() throws IOException { 7497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes FileInputStream fileIn = new FileInputStream(xmlFile); 7597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); 7697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int count; 7797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes byte[] buffer = new byte[1024]; 7897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes while ((count = fileIn.read(buffer)) != -1) { 7997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes bytesOut.write(buffer, 0, count); 8097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 8197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes fileIn.close(); 8297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes return bytesOut.toByteArray(); 8397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 8497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 8597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes public int timeSax(int reps) throws IOException, SAXException { 8697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int elementCount = 0; 8797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes for (int i = 0; i < reps; i++) { 8897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes inputStream.reset(); 8997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes ElementCounterSaxHandler elementCounterSaxHandler = new ElementCounterSaxHandler(); 9097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes saxParser.parse(inputStream, elementCounterSaxHandler); 9197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes elementCount += elementCounterSaxHandler.elementCount; 9297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 9397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes return elementCount; 9497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 9597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 9697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private static class ElementCounterSaxHandler extends DefaultHandler { 9797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int elementCount = 0; 9897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes @Override public void startElement(String uri, String localName, 9997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes String qName, Attributes attributes) { 10097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes elementCount++; 10197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 10297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 10397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 10497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes public int timeDom(int reps) throws IOException, SAXException { 10597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int elementCount = 0; 10697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes for (int i = 0; i < reps; i++) { 10797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes inputStream.reset(); 10897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes Document document = documentBuilder.parse(inputStream); 10997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes elementCount += countDomElements(document.getDocumentElement()); 11097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 11197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes return elementCount; 11297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 11397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 11497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private int countDomElements(Node node) { 11597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int result = 0; 11697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes for (; node != null; node = node.getNextSibling()) { 11797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes if (node.getNodeType() == Node.ELEMENT_NODE) { 11897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes result++; 11997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 12097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes result += countDomElements(node.getFirstChild()); 12197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 12297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes return result; 12397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 12497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 12597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes public int timeExpat(int reps) throws Exception { 12697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes return testXmlPull(expatConstructor, reps); 12797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 12897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 12997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes public int timeKxml(int reps) throws Exception { 13097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes return testXmlPull(kxmlConstructor, reps); 13197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 13297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 13397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes private int testXmlPull(Constructor<? extends XmlPullParser> constructor, int reps) 13497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes throws Exception { 13597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int elementCount = 0; 13697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes for (int i = 0; i < reps; i++) { 13797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes inputStream.reset(); 13897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes XmlPullParser xmlPullParser = constructor.newInstance(); 13997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes xmlPullParser.setInput(inputStream, "UTF-8"); 14097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes int type; 14197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes while ((type = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) { 14297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes if (type == XmlPullParser.START_TAG) { 14397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes elementCount++; 14497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 14597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 14697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 14797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes return elementCount; 14897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 14997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes 15097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes public static void main(String[] args) { 15197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes Runner.main(XmlParseBenchmark.class, args); 15297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes } 15397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes} 154