2011-03-29 34 views
0

使用Java對100MB XML文件進行排序需要多長時間?用Java對100MB XML文件排序?

文件有下列結構項目,我需要通過事件

<doc> 
    <id>84141123</id> 
    <title>kk+ at Hippie Camp</title> 
    <description>photo by SFP</description> 
    <time>18945840</time> 
    <tags>elphinstone tribalharmonix vancouver intention intention7 newyears hippiecamp bc sunshinecoast woowoo kk kriskrug sunglasses smoking unibomber møtleykrüg </tags> 
    <geo></geo> 
    <event>47409</event> 
</doc> 

我在英特爾雙雙核心和4GB RAM對它們進行排序。

分鐘?小時 ?

感謝

+10

建立它。衡量它。分享你學到的東西。我們無法推測您的代碼是如何顯示的,您的計算機運行速度有多慢,SAN的速度有多慢以及您的操作系統速度有多慢。但是,您可以通過生成假數據並寫入它來測量實際時間。你會發現解析輸入比創建輸出要慢。 – 2011-03-29 09:56:52

回答

2

我想說分鐘 - 你shud能夠做到完全在內存中,所以用SAX解析器,這將是閱讀排序寫作,不應該是你的硬件

問題
+2

*如果您在內存中執行此操作,則DOM解析器可能更合適,因爲您無需以此方式單獨構建內存中的數據表示形式。 – 2011-03-29 09:57:24

+0

但是,自定義內存中結構可能比DOM更緊湊。 – Thilo 2011-03-29 09:59:53

+1

我實際上正在考慮一個帶有事件id和xml項的項的樹圖 - 簡單的愚蠢的實現w/o任何xml魔術。 =) – atamur 2011-03-29 10:01:36

0

我覺得像這樣的問題會更好地使用序列化進行排序。

  1. 將XML文件反序列化爲'doc'的ArrayList。

  2. 使用直接的Java代碼,對事件屬性應用排序並將排序後的arraylist存儲在另一個變量中。

  3. 連載了排序「文檔」的ArrayList到文件

+0

要小心'ArrayList' - 當它擴展時,它分配的內存是它的兩倍。Imho,最好先掃描文件並計算''條目('grep | wc -l'這樣做很好),然後分配一個確切大小的數組。 – 9000 2011-03-29 10:15:50

+0

@ 9000,它是4 GB機器中的唯一一個100 MB文件。 2x擴展應該不成問題。 ;) – 2011-03-29 10:36:30

0

如果您在內存中做到這一點,你應該能夠做到這一點在10秒。你會在2秒鐘之內做這件事,因爲它會花費那麼多次讀/寫磁盤。

該程序應該使用不超過原始文件大小的4-5倍。你的情況下約500 MB。

String[] records = FileUtils.readFileToString(new File("my-file.xml")).split("</?doc>"); 
Map<Long, String> recordMap = new TreeMap<Long, String>(); 
for(int i=1;i<records.length;i+=2) { 
    String record = records[i]; 
    int pos1 = record.indexOf("<id>"); 
    int pos2 = record.indexOf("</id>", pos1+4); 
    long num = Long.parseLong(record.substring(pos1+3, pos2)); 
    recordMap.put(num, record); 
} 

StringBuilder sb = new StringBuilder(records[0]); 
for (String s : recordMap.values()) { 
    sb.append("<doc>").append(s).append("</doc>"); 
} 
sb.append(records[records.length-1]); 
FileUtils.writeStringToFile(new File("my-output-file.xml"), sb.toString()); 
7

下面是用於在100Mb的輸入文件中使用的XQuery撒克遜執行類似的任務的定時。

Saxon-EE 9.3.0.4J from Saxonica 
Java version 1.6.0_20 
Analyzing query from {for $i in //item order by location return $i} 
Analysis time: 195 milliseconds 
Processing file:/e:/javalib/xmark/xmark100.xml 
Using parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser 
Building tree for file:/e:/javalib/xmark/xmark100.xml using class net.sf.saxon.tree.tiny.TinyBuilder 
Tree built in 6158 milliseconds 
Tree size: 4787932 nodes, 79425460 characters, 381878 attributes 
Execution time: 3.466s (3466ms) 
Memory used: 471679816 

因此:解析輸入文件和構建樹大約需要6秒,對它進行排序需要3.5秒。這是從命令行調用的,但是從Java調用它將獲得非常類似的性能。不要試圖自己對代碼進行編碼 - 它只是一個單行查詢,而且你不太可能匹配優化的XQuery引擎的性能。

+1

+1。很好的答案。只要使用這個現有的工具,就不用費心去編寫已經存在於一個很好的,可訪問的打包解決方案中的代碼。 – Thilo 2011-03-30 01:19:06