2012-09-21 2 views
1

Я использую java default documentbuilder для анализа XML-документа, который содержит менее 100 строк кода. Для анализа документа потребуется 35 миллисекунд, для выполнения одного выражения xpath требуется 15 миллисекунд. Как я могу оптимизировать время, затрачиваемое как для xml, так и для парсера? ,XML Parser и выражение xpath

import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

import javax.xml.namespace.QName; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathConstants; 
import javax.xml.xpath.XPathExpressionException; 
import javax.xml.xpath.XPathFactory; 

import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.NamedNodeMap; 
import org.w3c.dom.NodeList; 
import org.xml.sax.SAXException; 


public class XMLParser { 


    public static final Logger LOGGER = Logger.getLogger(XMLParser.class.getName()); 

    private Map<String,List<NamedNodeMap>> fileVsProperties = new HashMap<String, List<NamedNodeMap>>(); 

    private Document document; 

    public XMLParser(File file){ 
      this.document = XMLUtil.getDocument(file); 
    } 

    public void setProperties(Element file){ 
     NodeList properties = file.getElementsByTagName("property"); 
     List<NamedNodeMap> props = new ArrayList<NamedNodeMap>(); 
     String type = file.getAttribute("type"); 
     String path = file.getAttribute("path"); 

     if("".equals(path)){ 
      LOGGER.log(Level.INFO,"Attribute path is required for a file."); 
      return; 
     } 

     path = path+":"+type; 

     for(int i = 0;i<properties.getLength();i++){ 
      Element property = (Element) properties.item(i); 
      props.add(property.getAttributes()); 
     } 
     setProperties(props,path); 
    } 

    private void setProperties(List<NamedNodeMap> properties , String path){ 
     List<NamedNodeMap> previousValue = fileVsProperties.get(path); 
     if(previousValue != null){ 
      previousValue.addAll(properties); 
     }else{ 
      fileVsProperties.put(path,properties); 
     } 

    } 

    public Element getConfiguration(String branchName) throws XPathExpressionException{ 
     return (Element)XMLUtil.getElements("/configurations/configuration[@name='"+branchName+"']",document.getDocumentElement(),XPathConstants.NODE); 
    } 

    public static void main(String[] args) throws XPathExpressionException { 
     long start = System.currentTimeMillis(); 
     File doc = new File("install.xml"); 
     XMLParser parser = new XMLParser(doc); 
     long end = System.currentTimeMillis(); 
     System.out.println("Time Taken For Parsing :: "+ (end-start) + " milliseconds"); 
     start = end; 
     Element configuration = parser.getConfiguration("BHARATHIKANNAN"); 
     end = System.currentTimeMillis(); 
     System.out.println("Time Taken For XPATH Expression TO Finding the Configuration :: "+ (end-start) + " milliseconds"); 
     start = end; 
     NodeList files = parser.getFiles(configuration); 
     for(int i=0;i<files.getLength();i++){ 
      parser.setProperties((Element) files.item(i)); 
     } 
     end = System.currentTimeMillis(); 
     System.out.println(parser.fileVsProperties); 
     System.out.println("Time Taken For Setting Properties :: "+ (end-start) + " milliseconds"); 
    } 

    public NodeList getFiles(Element configuration){ 
     return configuration.getElementsByTagName("file"); 
    } 

} 


class XMLUtil{ 
    private static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    private static DocumentBuilder builder; 
    public static final Logger LOGGER = Logger.getLogger(XMLUtil.class.getName()); 

    private static XPathFactory xpathFactory = XPathFactory.newInstance(); 

    private static XPath xpath; 

    static { 

     try { 
      builder = factory.newDocumentBuilder(); 
      xpath = xpathFactory.newXPath(); 
     } catch (ParserConfigurationException e) { 
      LOGGER.log(Level.INFO,""); 
     } 
    } 

    public static Document getDocument(File f){ 
     Document doc = null; 
     try { 
      doc = builder.parse(f); 
     } catch (SAXException e) { 
      LOGGER.log(Level.WARNING,"Invalid XML Document ",e); 
     } catch (IOException e) { 
      LOGGER.log(Level.SEVERE,"No Document Found in the given path",e); 
     } 
     return doc; 
    } 

    public static Object getElements(String xpathExpression , Element ele ,QName dataType) throws XPathExpressionException{ 
     return xpath.evaluate(xpathExpression, ele,dataType); 
    } 


} 

XML File

<?xml version="1.0"?> 
<!-- 
     Note : Default configuration loaded using your current branch name . You can extend configurations using extend attribute in configuration 
     node . 
--> 
<configurations> 
     <configuration name="default"> 
       <files> 
         <file type="xml" path="conf/server.xml.orig"> 
           <property regex="(port=).*" replace="\18080" xpath="/Server/Connector"></property> 
           <property regex="(port=).*" replace="\18080"></property> 
         </file> 
         <file type="text" path="conf/system_properties.conf"> 
           <property regex="(username=).*" replace="\1root" ></property> 
         </file> 
       </files> 
     </configuration> 
     <configuration name="BHARATHIKANNAN" extends="default"> 
       <files> 
         <file type="text" path="conf/system_properties.conf"> 
           <property regex="(username=).*" replace="\1root" ></property> 
         </file> 
       </files> 
     </configuration> 
</configurations> 

Выход: недавно спросил

Time Taken For Parsing :: 24 milliseconds 
Time Taken For XPATH Expression TO Finding the Configuration :: 14 milliseconds 
{conf/system_properties.conf:text=[[email protected]]} 
Time Taken For Setting Properties :: 0 milliseconds 
+1

Вы задаете 35 вопросов в своем вопросе, но в вашем журнале указано 24 мс. Что мне не хватает? –

+0

Hm, выход не показывает секунды, но миллисекунды! 24 и 14 миллисекунд, похоже, в порядке. – home

+0

Если это действительно о ms, почему вы хотите его оптимизировать? Производительность кажется мне прекрасной! – home

ответ

0

Кто-то об очень похожей задачи, но с гораздо большим документом (2Mb), и я дал некоторые саксонские тайминги здесь :

https://stackoverflow.com/questions/12497928/xpath-speed-comparision/12508614#12508614

Эти тайминги намного быстрее, чем вы видите, на гораздо большем документе. Поскольку вы уже используете Java, переход на саксонский язык должен быть очень простым.

Одно из предостережений заключается в том, что вы начинаете свои тайминги сразу после входа в main(), что означает, что вы в основном измеряете время загрузки класса, а не время обработки XML. Мои измерения позаботились о том, чтобы разогреть виртуальную машину Java до начала измерения.

Обратите внимание, что если вы используете Saxon, лучше всего использовать саксоновскую деревенскую модель, а не DOM или другие альтернативы. Недавно мы опубликовали некоторые измерения здесь:

http://dev.saxonica.com/blog/mike/2012/09/index.html#000194

DOM выходит 8 раз хуже, чем родное дерево саксонского в среднем, 23 раз хуже, в самом худшем случае.

Смежные вопросы