XmlPullParserにurlを渡すとものすごく遅い件
xmlの解析はDOMやSAXよりXMLPullPaserのほうが早い。でもってXMLPullPaserを使うときは、Inputstreamには文字列を使った方がはやい。直にURLを渡すのはやめたほうがいい。
■文字列を渡した場合
手順
手順は多いが実はこっちのほうがずっと早いことが判明
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; }
5回くらいやってみた。
文字列から解析した場合は平均 2〜3秒
URLから解析した場合は平均 12〜13秒
約10秒も差がある。
ただし、ファイルが膨大で解析を途中でやめてもいいとかで、ターゲットがすぐ見つかるとかならURLのほうが早いだろうけど、そこ臨機応変にいけばいい。