рдЬрдм рдореИрдВрдиреЗ рдПрдХ рдмрд╣реБрдд-рд╕реА рдирд┐рдпрдорд┐рдд рдПрдХреНрд╕рдПрдордПрд▓ рдлрд╝рд╛рдЗрд▓ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХреЗрд╡рд▓ рдПрдХ рд╣рдЬрд╛рд░ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ) рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рддреЛ рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рдХрд┐ рдПрдХреНрд╕рдбреИрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдирд┐рд╖реНрдХрд░реНрд╖рдг рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдиреЛрдбрд▓рд┐рд╕реНрдЯ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд╛рдлреА рдзреАрдореА рдЧрддрд┐ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ (рдореЗрд░реА рдлрд╛рдЗрд▓ рдкрд░ рд▓рдЧрднрдЧ 2 рдорд┐рдирдЯ рд▓рдЧрддреЗ рд╣реИрдВ), рдФрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдмреНрд░реЗрдХ рдмрдврд╝ рдЬрд╛рддреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдж рдХрд╛ рдиреЛрдб (рдиреЛрдб)ред рдпрд╣ рд╕рдорд╕реНрдпрд╛ рднреА рд╕рд╛рдордиреЗ рдЖрддреА рд╣реИред
blog.astradele.com/2006/02/24/slow-xpath-evaluation-for-large-xml-documents-in-java-15jbwhammie.blogspot.com/2011/02/make-java-xpath-work-on-large-files.htmlрдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВ, рдпрд╣ JDK рдореЗрдВ DOM & XPath рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдХреБрдЫ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЗрд╕ рддрдереНрдп рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ рдХрд┐ рдЕрдЧрд░ рд╣рдореЗрдВ XPath рдЕрдиреБрд░реЛрдз рд╕реЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд XML рдиреЛрдб рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдиреЛрдб рдорд╛рддрд╛-рдкрд┐рддрд╛ рджреНрд╡рд╛рд░рд╛ XML рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдВрджрд░реНрднрд┐рдд рд░рд╣рддрд╛ рд╣реИред рдФрд░ рдмрд╛рдж рдореЗрдВ рдЗрд╕ рдиреЛрдб рдХреЗ рд▓рд┐рдП XPath рдЕрдиреБрд░реЛрдз рдЗрд╕ рддрдереНрдп рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рди рдХреЗрд╡рд▓ рдЦреБрдж рдиреЛрдб рдмрд▓реНрдХрд┐ рдкреВрд░реЗ XML рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд╕рдВрд╕рд╛рдзрд┐рдд рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЛ рдиреЛрдб рд╕реЗ рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдирд╛ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдиреЛрдб рдХреЛ рдЗрд╕рдХреЗ рдореВрд▓ рдиреЛрдб рд╕реЗ рд╣рдЯрд╛рдХрд░ред рдпрд╣ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдКрдкрд░ рджрд┐рдП рдЧрдП рд▓рд┐рдВрдХ рдкрд░ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдПрдХрдорд╛рддреНрд░ рджреЛрд╖ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ XML рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рд╣реА рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдпрд╣ рдЖрдЧреЗ рдбреЗрдЯрд╛ рдирд┐рд╖реНрдХрд░реНрд╖рдг рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд░рд╣ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рдХрд┐ рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рд╣реИ рдЬреЛ XML рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рд╕реНрд╡рдпрдВ рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ - рдХреНрд▓реЛрди рдиреЛрдб, рдХреНрдпреЛрдВрдХрд┐, рдкреНрд░рд▓реЗрдЦрди рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдХреНрд▓реЛрди рдореЗрдВ
рдкреИрд░реЗрдВрдЯ = рдЕрд╢рдХреНрдд рд╣реИ ред
рджрд░рдЕрд╕рд▓, рд╡рд░реНрдгрд┐рдд рд╕рдорд╕реНрдпрд╛ рдФрд░ рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП рджреГрд╖реНрдЯрд┐рдХреЛрдг рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рд╕рдЪрд┐рддреНрд░ рд╣реИрдВред
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.ByteArrayInputStream;
public class SlowXPath {
public static void main( String [] args) throws Exception {
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
String xmlString = prepareXml(5000);
// System.out.println(xmlString);
final Document xmlDoc = documentBuilder.parse( new ByteArrayInputStream(xmlString.getBytes()));
final XPathFactory xPathFactory = XPathFactory.newInstance();
final XPathExpression nodeXPath = xPathFactory.newXPath().compile( "//node" );
final XPathExpression iXPath = xPathFactory.newXPath().compile( "./i/text()" );
final NodeList nodeList = (NodeList) nodeXPath.evaluate(xmlDoc, XPathConstants.NODESET);
System. out .println( "Nodes number=" + nodeList.getLength());
timeIt( "Simple iterate" , new Runnable() {
@Override
public void run() {
int sum = 0;
for ( int i = 0; i < nodeList.getLength(); i++) {
final Node node = nodeList.item(i);
try {
final String iStr = ( String ) iXPath.evaluate(node, XPathConstants.STRING);
sum += Integer.parseInt(iStr.trim());
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
System. out .println( "Sum=" + sum);
}
});
timeIt( "Iterate with cloning" , new Runnable() {
@Override
public void run() {
int sum = 0;
for ( int i = 0; i < nodeList.getLength(); i++) {
final Node node = nodeList.item(i).cloneNode( true ); // <-- Note cloning here
try {
final String iStr = ( String ) iXPath.evaluate(node, XPathConstants.STRING);
sum += Integer.parseInt(iStr.trim());
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
System. out .println( "Sum=" + sum);
}
});
timeIt( "Iterate with detaching node" , new Runnable() {
@Override
public void run() {
int sum = 0;
for ( int i = 0; i < nodeList.getLength(); i++) {
final Node node = nodeList.item(i);
node.getParentNode().removeChild(node); // <-- Note detaching node
try {
final String iStr = ( String ) iXPath.evaluate(node, XPathConstants.STRING);
sum += Integer.parseInt(iStr.trim());
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
System. out .println( "Sum=" + sum);
}
});
}
private static String prepareXml( int n) {
StringBuilder sb = new StringBuilder ();
sb.append( "<root>" );
for ( int i = 0; i < n; i++) {
sb.append( "<node><i>\n" )
.append(i)
.append( "</i></node>\n" );
}
sb.append( "</root>" );
return sb.toString();
}
private static void timeIt( String name, Runnable runnable) {
long t0 = System.currentTimeMillis();
runnable.run();
long t1 = System.currentTimeMillis();
System. out .println(name + " executed " + ((t1 - t0) / 1000f) + "sec." );
}
}
* This source code was highlighted with Source Code Highlighter .
рдФрд░ рдпрд╣рд╛рдБ рдХрд╛рдо рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИ:
Nodes number=5000
Sum=12497500
Simple iterate executed 17.359sec.
Sum=12497500
Iterate with cloning executed 1.047sec.
Sum=12497500
Iterate with detaching node executed 1.031sec.