Cargando XML es muy lento
-
29-09-2019 - |
Pregunta
I heredó un almacenamiento de datos que estaba usando simples archivos de texto para guardar documentos.
Documentos tenían algunos atributos (fecha, título y texto), y éstos fueron codificados en un nombre de archivo:.
Sin embargo, en los documentos de realidad en el sistema tienen muchos atributos más, e incluso más nuevo se propone añadir.
Parecía lógico para cambiar a un formato XML, y lo he hecho, con cada documento ahora codificado en su propio archivo XML.
Sin embargo, la lectura de los archivos XML a partir de ahora es ridículamente lento! (¿Dónde 2000 artículos en el formato .txt tomaron segundos, ahora 2000 artículos en el formato .xml tarda más de 10 minutos).
Yo estaba usando un analizador DOM, y después de que descubrí cómo retardar la lectura era, me cambié a un analizador SAX, sin embargo aún así es tan lenta (bueno, más rápido, pero todavía 10 minutos).
es XML JUSTO QUE lenta, o estoy haciendo algo extraño? se agradecería cualquier pensamiento.
El sistema está escrito en JavaSE 1.6. El analizador se crea de esta manera:
/*
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
*/
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser;
try {
saxParser = factory.newSAXParser();
ArticleSaxHandler handler = new ArticleSaxHandler();
saxParser.parse(is, handler);
return handler.getArticle();
} catch (ParserConfigurationException e) {
throw new IOException(e);
} catch (SAXException e) {
throw new IOException(e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
logger.error(e);
}
}
}
}
private class ArticleSaxHandler extends DefaultHandler {
private URI uri = null;
private String source = null;
private String author = null;
private DateTime articleDatetime = null;
private DateTime processedDatetime = null;
private String title = null;
private String text = null;
private ArticleElement currentElement;
private final StringBuilder builder = new StringBuilder();
public Article getArticle() {
return new Article(uri, source, author, articleDatetime, processedDatetime, title, text);
}
/** Receive notification of the start of an element. */
public void startElement(String uri, String localName, String qName, Attributes attributes) {
if (builder.length() != 0) {
throw new RuntimeException(new SAXParseException(currentElement + " was not finished before " + qName + " was started", null));
}
currentElement = ArticleElement.getElement(qName);
}
public void endElement(String uri, String localName, String qName) {
final String elementText = builder.toString();
builder.delete(0, builder.length());
if (currentElement == null) {
return;
}
switch (currentElement) {
case ARTICLE:
break;
case URI:
try {
this.uri = new URI(elementText);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
break;
case SOURCE:
source = elementText;
break;
case AUTHOR:
author = elementText;
break;
case ARTICLE_DATE_TIME:
articleDatetime = getDateTimeFormatter().parseDateTime(elementText);
break;
case PROCESSED_DATE_TIME:
processedDatetime = getDateTimeFormatter().parseDateTime(elementText);
break;
case TITLE:
title = elementText;
break;
case TEXT:
this.text = elementText;
break;
default:
throw new IllegalStateException("Unexpected ArticleElement: " + currentElement);
}
currentElement = null;
}
/** Receive notification of character data inside an element. */
public void characters(char[] ch, int start, int length) {
builder.append(ch, start, length);
}
public void error(SAXParseException e) {
fatalError(e);
}
public void fatalError(SAXParseException e) {
logger.error("currentElement: " + currentElement + " ||builder: " + builder.toString() + "\n\n" + e.getMessage(), e);
}
}
private enum ArticleElement {
ARTICLE(ARTICLE_ELEMENT_NAME), URI(URI_ELEMENT_NAME), SOURCE(SOURCE_ELEMENT_NAME), AUTHOR(AUTHOR_ELEMENT_NAME), ARTICLE_DATE_TIME(
ARTICLE_DATETIME_ELEMENT_NAME), PROCESSED_DATE_TIME(PROCESSED_DATETIME_ELEMENT_NAME), TITLE(TITLE_ELEMENT_NAME), TEXT(TEXT_ELEMENT_NAME);
private String name;
private ArticleElement(String name) {
this.name = name;
}
public static ArticleElement getElement(String qName) {
for (ArticleElement element : ArticleElement.values()) {
if (element.name.equals(qName)) {
return element;
}
}
return null;
}
}
Solución
La lectura de datos a partir de una corriente sin búfer podría explicar estos problemas de rendimiento. Esto no está directamente relacionada con el cambio de texto a XML pero tal vez por casualidad, su nueva aplicación no utiliza un BufferedInputStream
más.
follwing ese camino, en detalle, cheque si esto es amortiguada is
:
saxParser.parse(is, handler);