2010-08-19 7 views
2

간단한 텍스트 파일을 사용하여 데이터를 저장하는 데이터 저장소를 상속했습니다.XML 로딩 속도가 매우 느림

문서의 파일 이름은 <> < title> .txt이며 파일 본문이 텍스트 인 일부 파일 이름 (날짜, 제목 및 텍스트)으로 인코딩되었습니다.

그러나 실제로는 시스템의 문서에는 더 많은 특성이 있으며 더 많이 추가되도록 제안되었습니다.

XML 형식으로 전환하는 것이 논리적 인 것처럼 보였습니다. 이제 XML 형식으로 인코딩 된 각 문서를 사용하여 XML 형식으로 전환했습니다.

그러나 XML에서 파일을 읽는 것은 이제 아주 느립니다! (.txt 형식의 2000 개 기사가 초 단위로 작성된 지금은 .xml 형식의 2000 개 기사가 10 분 이상 소요됩니다.)

나는 DOM 파서를 사용하고 있었고 읽기가 얼마나 느린지를 발견 한 후 SAX 파서로 전환했지만 느린 속도 (물론 더 빠르지 만 여전히 10 분)가되었습니다.

XML이 느린지 아니면 이상한 일을하고 있습니까? 어떤 생각이라도 감사 할 것입니다.

시스템은 JavaSE 1.6으로 작성되었습니다. 파서는 다음과 같이 생성됩니다 :

 

/* 
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; 
     } 
    } 
 
+0

없음 XML가 느린 아니라, 본질적으로 :


하면이 is 버퍼링되어 있는지 확인 구체적으로, 해당 경로를 follwing을. 프로파일 러를 잡고 느린 부분을 확인하십시오. –

+2

코드 샘플을 게시하지 않으면 "이상한 일을하고 있는지"알 수 없습니다. –

+0

2000 문서 파일의 크기는 얼마입니까? VM에 얼마만큼의 메모리를 부여 했습니까? CPU 사용량은 어떻습니까? –

답변

6

읽기 데이터를 버퍼링 스트림에서 이러한 성능 문제를 설명 할 수있다. 이것은 텍스트에서 XML 로의 변경과 직접적인 관련이 없지만 우연히 새로운 구현에서는 BufferedInputStream을 더 이상 사용하지 않습니다.

saxParser.parse(is, handler); 
+0

이것이 내가해야한다고 생각합니다. 실제로 경로를 따르지는 않았지만 단순히 줄을 변경했습니다. saxParser.parse (is, handler); saxParser.parse (새로운 BufferedInputStream (is), 핸들러); 기사 당 10 ~ 40 밀리미터 (또는 2000 ~ 16 초) – barryred

관련 문제