2

コードが 100 行未満の xml ドキュメントを解析するために、Java のデフォルトの documentbuilder を使用しています。ドキュメントの解析には 35 ミリ秒かかり、1 つの xpath 式の実行には 15 ミリ秒かかります。xml とパーサーの両方にかかる時間を最適化するにはどうすればよいですか? .

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 ファイル

    <?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=[com.sun.org.apache.xerces.internal.dom.AttributeMap@75d9fd51]}
Time Taken For Setting Properties :: 0 milliseconds
4

1 に答える 1

0

最近、非常によく似たタスクについて誰かが尋ねましたが、ドキュメントははるかに大きく (2Mb) ありました。

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

これらのタイミングは、はるかに大きなドキュメントで見ているよりもはるかに高速です。すでに Java を使用しているため、Saxon への切り替えは非常に簡単です。

ただし、1 つの注意点は、main() へのエントリですぐにタイミングを開始することです。これは、XML 処理時間ではなく、主にクラスの読み込み時間を測定していることを意味します。私の測定では、測定を開始する前に Java VM をウォームアップするように注意しました。

Saxon を使用している場合は、DOM やその他の代替手段ではなく、Saxon のネイティブ ツリー モデルを使用する方がはるかに優れていることに注意してください。最近、ここでいくつかの測定値を公開しました。

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

DOM は、Saxon のネイティブ ツリーよりも平均で 8 倍悪く、最悪の場合は 23 倍悪くなります。

于 2012-09-21T13:41:38.367 に答える