Home | History | Annotate | Download | only in benchmarks
      1 /*
      2  * Copyright (C) 2010 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package benchmarks;
     18 
     19 import com.google.caliper.BeforeExperiment;
     20 import com.google.caliper.Param;
     21 import java.io.ByteArrayInputStream;
     22 import java.io.ByteArrayOutputStream;
     23 import java.io.FileInputStream;
     24 import java.io.IOException;
     25 import java.lang.reflect.Constructor;
     26 import java.util.Arrays;
     27 import java.util.List;
     28 import javax.xml.parsers.DocumentBuilder;
     29 import javax.xml.parsers.DocumentBuilderFactory;
     30 import javax.xml.parsers.SAXParser;
     31 import javax.xml.parsers.SAXParserFactory;
     32 import org.w3c.dom.Document;
     33 import org.w3c.dom.Node;
     34 import org.xml.sax.Attributes;
     35 import org.xml.sax.SAXException;
     36 import org.xml.sax.helpers.DefaultHandler;
     37 import org.xmlpull.v1.XmlPullParser;
     38 
     39 public class XmlParseBenchmark {
     40 
     41     @Param String xmlFile;
     42     ByteArrayInputStream inputStream;
     43 
     44     static List<String> xmlFileValues = Arrays.asList(
     45             "/etc/apns-conf.xml",
     46             "/etc/media_profiles.xml",
     47             "/etc/permissions/features.xml"
     48     );
     49 
     50     private SAXParser saxParser;
     51     private DocumentBuilder documentBuilder;
     52     private Constructor<? extends XmlPullParser> kxmlConstructor;
     53     private Constructor<? extends XmlPullParser> expatConstructor;
     54 
     55     @SuppressWarnings("unchecked")
     56     @BeforeExperiment
     57     protected void setUp() throws Exception {
     58         byte[] xmlBytes = getXmlBytes();
     59         inputStream = new ByteArrayInputStream(xmlBytes);
     60         inputStream.mark(xmlBytes.length);
     61 
     62         SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
     63         saxParser = saxParserFactory.newSAXParser();
     64 
     65         DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
     66         documentBuilder = builderFactory.newDocumentBuilder();
     67 
     68         kxmlConstructor = (Constructor) Class.forName("org.kxml2.io.KXmlParser").getConstructor();
     69         expatConstructor = (Constructor) Class.forName("org.apache.harmony.xml.ExpatPullParser")
     70                 .getConstructor();
     71     }
     72 
     73     private byte[] getXmlBytes() throws IOException {
     74         FileInputStream fileIn = new FileInputStream(xmlFile);
     75         ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
     76         int count;
     77         byte[] buffer = new byte[1024];
     78         while ((count = fileIn.read(buffer)) != -1) {
     79             bytesOut.write(buffer, 0, count);
     80         }
     81         fileIn.close();
     82         return bytesOut.toByteArray();
     83     }
     84 
     85     public int timeSax(int reps) throws IOException, SAXException {
     86         int elementCount = 0;
     87         for (int i = 0; i < reps; i++) {
     88             inputStream.reset();
     89             ElementCounterSaxHandler elementCounterSaxHandler = new ElementCounterSaxHandler();
     90             saxParser.parse(inputStream, elementCounterSaxHandler);
     91             elementCount += elementCounterSaxHandler.elementCount;
     92         }
     93         return elementCount;
     94     }
     95 
     96     private static class ElementCounterSaxHandler extends DefaultHandler {
     97         int elementCount = 0;
     98         @Override public void startElement(String uri, String localName,
     99                 String qName, Attributes attributes) {
    100             elementCount++;
    101         }
    102     }
    103 
    104     public int timeDom(int reps) throws IOException, SAXException {
    105         int elementCount = 0;
    106         for (int i = 0; i < reps; i++) {
    107             inputStream.reset();
    108             Document document = documentBuilder.parse(inputStream);
    109             elementCount += countDomElements(document.getDocumentElement());
    110         }
    111         return elementCount;
    112     }
    113 
    114     private int countDomElements(Node node) {
    115         int result = 0;
    116         for (; node != null; node = node.getNextSibling()) {
    117             if (node.getNodeType() == Node.ELEMENT_NODE) {
    118                 result++;
    119             }
    120             result += countDomElements(node.getFirstChild());
    121         }
    122         return result;
    123     }
    124 
    125     public int timeExpat(int reps) throws Exception {
    126         return testXmlPull(expatConstructor, reps);
    127     }
    128 
    129     public int timeKxml(int reps) throws Exception {
    130         return testXmlPull(kxmlConstructor, reps);
    131     }
    132 
    133     private int testXmlPull(Constructor<? extends XmlPullParser> constructor, int reps)
    134             throws Exception {
    135         int elementCount = 0;
    136         for (int i = 0; i < reps; i++) {
    137             inputStream.reset();
    138             XmlPullParser xmlPullParser = constructor.newInstance();
    139             xmlPullParser.setInput(inputStream, "UTF-8");
    140             int type;
    141             while ((type = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) {
    142                 if (type == XmlPullParser.START_TAG) {
    143                     elementCount++;
    144                 }
    145             }
    146         }
    147         return elementCount;
    148     }
    149 }
    150