2

単純なテキストファイルを使用してドキュメントを保存していたデータストレージを継承しました。

ドキュメントにはいくつかの属性(日付、タイトル、テキスト)があり、これらはファイル名<date>-<title> .txtにエンコードされており、ファイルの本文はテキストです。

ただし、実際には、システム内のドキュメントにはさらに多くの属性があり、さらに多くの属性を追加することが提案されています。

XML形式に切り替えるのは理にかなっているようで、私はそうしました。各ドキュメントは、独自のXMLファイルにエンコードされています。

ただし、XMLからのファイルの読み込みは、途方もなく遅くなりました。(.txt形式の2000の記事は数秒かかりましたが、.xml形式の2000の記事は10分以上かかります)。

私はDOMパーサーを使用していましたが、読み取りがどれほど遅いかを発見した後、SAXパーサーに切り替えましたが、それでも同じくらい遅いです(まあ、高速ですが、それでも10分です)。

XMLはそれだけ遅いですか、それとも私は何か奇妙なことをしていますか?どんな考えでもいただければ幸いです。

システムはJavaSE1.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;
        }
    }

4

2 に答える 2

6

バッファリングされていないストリームからデータを読み取ると、これらのパフォーマンスの問題を説明できる可能性があります。これは、テキストからXMLへの変更に直接関係していませんが、たまたま新しい実装で使用されなくなった可能性がありBufferedInputStreamます。


そのパスをたどって、詳細に、これisがバッファリングされているかどうかを確認します。

saxParser.parse(is, handler);
于 2010-08-19T11:09:22.487 に答える
0

SAXパーサーを使用した読み込みが遅い場合にも、この問題が発生しました。この問題は、実際にはW3CからのDTD参照を持つXMLファイルに関連していました。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
<html xmlns="http://www.w3.org/TR/1999/REC-html-in-xml" xml:lang="en"
      lang="en">

SAXとXMLに関する「コアJava、ボリュームII」の第2章からの抜粋では、何が起こっているのか、またアドレスを追加する方法について説明しています。

XHTMLファイルはDTD参照を含むタグで始まり、パーサーはそれをロードする必要があります。当然のことながら、W3Cは、www.w3.org / TR / xhtml1 / DTD/xhtml1-strict.dtdなどのファイルの何十億ものコピーを提供することに満足していません。ある時点で、彼らは完全に拒否しましたが、この記事の執筆時点では、彼らは氷河のペースでDTDにサービスを提供しています。ドキュメントを検証する必要がない場合は、

SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

これで修正されました。さらに、IntelliJ IDEを使用して、XMLファイルに追加の(不要な)<HTML>タグと追加のが含まれていることを示しました<meta charset="UTF-8"/>。それは私にいくつかのSAX例外を取り除くのを助けました。

于 2020-05-24T04:46:27.993 に答える