2011-03-29 4 views
0

Java로 100MB XML 파일을 정렬하는 데 얼마나 걸리나요?100MB XML 파일을 Java로 정렬 하시겠습니까?

파일은 다음과 같은 구조의 항목을 가지고 있는데 인텔 듀얼 코어 듀오 4GB의 RAM에 이벤트

<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> 

난별로 정렬 할 필요가있다.

분? 시간 ?

감사

+10

빌드하십시오. 그것을 측정하십시오. 배운 것을 공유하십시오. 우리는 당신의 코드가 어떻게 보이는지, 컴퓨터가 얼마나 느린지, SAN이 얼마나 느린지, OS가 얼마나 느린 지에 대해서는 추측 할 수 없습니다. 그러나 가짜 데이터를 생성하고이를 쓰면 실제 시간을 측정 할 수 있습니다. 입력을 파싱하는 것이 출력을 만드는 것보다 느리다는 것을 알 수 있습니다. –

답변

2

나는 분을 말할 것이다 - 당신이 읽기 - 정렬 쓰기가 될 것이라고 색소폰 파서 있도록 완전히 메모리 내 그렇게 할 수 shud, 하드웨어

에 대한 문제가되지 않습니다
+2

* 메모리 내에서 수행하는 경우, DOM 파서가 더 적절할 수 있습니다. 이렇게하면 데이터의 메모리 내 별도 표현을 이런 식으로 작성할 필요가 없기 때문입니다. –

+0

그러나 맞춤형 인 메모리 구조는 DOM보다 훨씬 더 작을 수 있습니다. – Thilo

+1

사실 이벤트 ID와 아이템의 키가있는 트리 맵을 생각하고있었습니다. 모든 xml 마법을 사용하는 일반 멍청한 구현이었습니다. =) – atamur

0

이 문제는 직렬화를 사용하면 더 잘 정리 될 것이라고 생각합니다.

  1. XML 파일을 'doc'의 ArrayList로 deserialise하십시오.

  2. 직선 자바 코드를 사용하여 이벤트 속성에 정렬을 적용하고 정렬 된 arraylist를 다른 변수에 저장하십시오. 정렬 된 '문서'ArrayList를

  3. 직렬화를 밖으로 당신이 메모리에 그것을 할 경우, 10 초 미만이에 할 수 있어야

+0

'ArrayList'주의 - 확장 될 때, 그것은 두 배의 메모리를 할당한다.Imho, 먼저 파일을 검사하고''항목을 계산하는 것이 좋습니다 ('grep | wc -l'이이 작업을 잘 수행합니다). 그런 다음 정확한 크기의 배열을 할당하십시오. – 9000

+0

@ 9000, 4GB 컴퓨터에있는 100MB 파일. 2 배 확장은 문제가되지 않습니다. ;) –

0

를 제출합니다. 디스크를 읽고 쓰는 데 많은 시간을 할애하기 때문에 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 입력 파일에서 Saxon 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 

입력 파일을 구문 분석하고 트리를 작성하는 데 약 3.5 초, 정렬하려면 약 6 초. 명령 줄에서 호출하지만 Java에서 호출하면 매우 비슷한 성능을 얻을 수 있습니다. 정렬을 직접 코딩하지 마십시오. 단 한 줄짜리 쿼리 일 뿐이므로 최적화 된 XQuery 엔진의 성능을 일치시킬 가능성은 거의 없습니다.

+1

+1. 좋은 대답. 이 기존 도구를 사용하고 이미 접근성이 좋고 접근하기 쉬운 패키지 솔루션에 이미 나와있는 코드 작성을 신경 쓸 필요가 없습니다. – Thilo

관련 문제