XmlPullParserにurlを渡すとものすごく遅い件

xmlの解析はDOMやSAXよりXMLPullPaserのほうが早い。でもってXMLPullPaserを使うときは、Inputstreamには文字列を使った方がはやい。直にURLを渡すのはやめたほうがいい。
■文字列を渡した場合
手順

  • XMLをByte配列で取得
  • Byte配列→文字列
  • 文字列をXmlPullParserにかます

手順は多いが実はこっちのほうがずっと早いことが判明
getByteArrayFromURLメソッドは前の記事参照

	public static ArrayList<String> getXmlTags(String url, String[] targetTags) {
		byte[] byteArray = Utils.getByteArrayFromURL(url);
		ArrayList<String> result = new ArrayList<String>();
		if (byteArray == null) {
			Log.i("getXmlTags", "URLの取得に失敗");
			return result;
		}
		String data = new String(byteArray);

		try {
			final XmlPullParser xpp = Xml.newPullParser();
			xpp.setInput(new StringReader(data));
			while (true) {
				int e = xpp.getEventType();

				// EventがEND_DOCUMENTなら終了
				if (e == XmlPullParser.END_DOCUMENT) {
					break;
				}

				e = xpp.next();
				switch (e) {
				case XmlPullParser.START_TAG:
					String tag = xpp.getName();
					for (String target : targetTags) {
						if (target.equals(tag)) {
							result.add(xpp.nextText());
							break;
						}
					}
					break;
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

■URLを渡した場合
ストリームで一行ずつ取得し、コネクションはったままの状態で1行ずつ解析を行う。中で何やっているのかとにかく遅い。
そしてcloseしてなかった・・・。

	public static ArrayList<String> getXMLFromURL(String url, String[] targetTags) {
		ArrayList<String> result = new ArrayList<String>();
		XmlPullParser xpp = null;

		try {
			URL rssurl = new URL(url);
			XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
			factory.setNamespaceAware(true);
			xpp = factory.newPullParser();
			InputStream is = rssurl.openStream();
			xpp.setInput(is, "UTF-8");

			while (true) {
				int e = xpp.getEventType();
				if (e == XmlPullParser.END_DOCUMENT) {
					break;
				} else {

					e = xpp.nextToken();
					String tag;
					tag = xpp.getName();
					switch (e) {
					case XmlPullParser.START_TAG:
						for (String target : targetTags) {
							if (target.equals(tag)) {
								result.add(xpp.nextText());
								break;
							}
						}
					}
				}
			}

		} catch (XmlPullParserException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}

		return result;
	}

■結果
文字列から解析した場合

URLから解析した場合

5回くらいやってみた。
文字列から解析した場合は平均 2〜3秒
URLから解析した場合は平均 12〜13秒
約10秒も差がある。
ただし、ファイルが膨大で解析を途中でやめてもいいとかで、ターゲットがすぐ見つかるとかならURLのほうが早いだろうけど、そこ臨機応変にいけばいい。