次のように、対応する緯度と経度を含む郵便番号を含む一連の XML があります。
<?xml version="1.0"?>
<postcodes>
<entry postcode='AB1 0AA' latitude='7.101478' longitude='2.242852' />
<entry postcode='AB1 0AB' latitude='7.201458' longitude='2.122952' />
</postcodes>
XML は特定の文字で始まる郵便番号に分割されるため、アルファベットの文字ごとに 1 つの XML があります。それらの間には、英国内のすべての郵便番号が含まれています。つまり、これらの XML ファイルの最大のものには 300,000entry
の要素が含まれています。
Entity オブジェクトのリストをループして、郵便番号を SAX 経由で配置し、各郵便番号に対してlongitude
とのlatitude
値を取得しています。したがって、2000 個のエンティティ オブジェクトがある場合、SAX ハンドラを 2000 回実行してそれらの値を取得します。以下のループのコード。
em = emf.createEntityManager();
for (Integer id : siteID){
site = em.find(SiteTable.class, id);
if(site != null && site.getPostcode() != null && !site.getPostcode().equals("")){
XMLPositionRetriever.runXMLQuery(site.getPostcode());
}
else{
System.out.println("The site and/or postcode against this Instruction does not exist.");
}
}
em.close();
site.getPostcode()
postcodeToFind
Handler になります。以下で使用されている唯一の SAX Handler メソッドのコード。
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (postcodeToFind.equals(attributes.getValue("postcode"))){
System.out.println("The postcode '"+postcodeToFind+"', has a latitude of "+attributes.getValue("latitude")+" and a longitude of "+attributes.getValue("longitude"));
throw new SAXException();
}
}
現在、これには時間がかかります (2000 回の検索で 4 分弱かかります) が、ロード時間を速くする必要があります。できれば30秒以内。これまでのところ、ロード時間を半分以下に短縮することができました。
- Handler を実行しなければならない回数を、必要な回数だけに削減します (チェックする必要のあるエンティティの数を減らすことによって)。
- 必要なデータが見つかったら startElement() メソッドで例外をスローするようにして、不必要に検索を続けないようにします。
- XML ファイルを小さなファイル (アルファベットの文字ごとに 1 つ) に分割して、ハンドラーがファイルごとにチェックする要素を少なくします。
Q: SAX をより効率的に処理するための提案はありますか?