2010-11-17 46 views
9

Tôi đang viết một ứng dụng xử lý nhiều tệp xml (> 1000) với cấu trúc nút sâu. Mất khoảng sáu giây với woodstox (API sự kiện) để phân tích cú pháp tệp với 22.000 Nút.Phân tích cú pháp XML song song trong Java

Thuật toán được đặt trong quá trình tương tác với người dùng, trong đó chỉ một vài giây thời gian phản hồi có thể chấp nhận được. Vì vậy, tôi cần phải cải thiện chiến lược cách xử lý các tệp xml.

  1. Quy trình của tôi phân tích tệp xml (chỉ trích xuất một vài nút).
  2. Nút được giải nén được xử lý và kết quả mới được ghi vào luồng dữ liệu mới (dẫn đến bản sao của tài liệu có các nút đã sửa đổi).

Bây giờ tôi đang suy nghĩ về một giải pháp đa luồng (có quy mô tốt hơn trên 16 lõi + phần cứng). Tôi đã nghĩ về những điều sau đây:

  1. Tạo nhiều trình phân tích cú pháp và chạy chúng song song với nguồn xml.
  2. Viết lại thuật toán phân tích cú pháp của tôi thread-lưu vào sử dụng chỉ có một thể hiện của phân tích cú pháp (nhà máy, ...)
  3. Chia nguồn XML vào khối và gán các khối để nhiều luồng xử lý (map-reduce xml - serial)
  4. Tối ưu hóa của tôi thuật toán (trình phân tích cú pháp StAX tốt hơn so với woodstox?)/Sử dụng trình phân tích cú pháp với tính năng đồng thời tích hợp

Tôi muốn cải thiện cả hiệu suất tổng thể và hiệu suất "cho mỗi tệp".

Bạn có gặp phải vấn đề như vậy không? Cách tốt nhất để đi là gì?

+0

Không rõ cần tối đa hóa gì ở đây ... hiệu suất trên tệp SINGLE hoặc tổng hiệu suất trên tất cả 1000 tệp. –

+0

Một đề xuất khác: nếu bạn có thể định lượng kích thước tệp, để cho phép tính toán trong suốt (megabyte trên giây được xử lý), nó có thể đưa ra ý tưởng về hiệu suất dự kiến. Tôi thường nhận được 10 - 40 MB/s để phân tích cú pháp với Woodstox khi thử nghiệm; nhưng ổ đĩa cứng của tôi chỉ có thể cung cấp 5 - 10 MB/s tốc độ bền vững. – StaxMan

+0

Bạn đã xem vtd-xml chưa? nó là trạng thái của nghệ thuật trong xử lý nhiệm vụ nặng nề ... nó hiệu quả hơn nhiều so với SAX hay stax? –

Trả lời

4
  1. Điều này rõ ràng: chỉ cần tạo một số trình phân tích cú pháp và chạy chúng song song trong nhiều chuỗi.

  2. Hãy xem Woodstox Performance (tại thời điểm này, hãy thử bộ nhớ cache của Google).

  3. Điều này có thể được thực hiện NẾU cấu trúc của XML của bạn có thể dự đoán được: nếu nó có nhiều phần tử cấp cao nhất. Ví dụ:

    <element> 
        <more>more elements</more> 
    </element> 
    <element> 
        <other>other elements</other> 
    </element> 
    

    Trong trường hợp này, bạn có thể tạo bộ tách đơn giản tìm kiếm <element> và cấp phần này cho một trình phân tích cú pháp cụ thể.Đó là một cách tiếp cận đơn giản: trong cuộc sống thực tôi muốn đi với RandomAccessFile để tìm điểm dừng bắt đầu (<element>) và sau đó tạo FileInputStream tùy chỉnh chỉ hoạt động trên một phần của tệp.

  4. Hãy xem Aalto. Cùng những kẻ đã tạo ra Woodstox. Đây là những chuyên gia trong lĩnh vực này - đừng sáng tạo lại bánh xe.

4

Tôi đồng ý với Jim. Tôi nghĩ rằng nếu bạn muốn cải thiện hiệu suất xử lý tổng thể của 1000 tệp, kế hoạch của bạn là tốt, ngoại trừ # 3 không liên quan trong trường hợp này. Tuy nhiên, nếu bạn muốn cải thiện hiệu suất phân tích cú pháp của tệp đơn bạn gặp sự cố. Tôi không biết làm thế nào nó có thể phân chia tập tin XML mà không có nó phân tích cú pháp. Mỗi đoạn sẽ là XML bất hợp pháp và trình phân tích cú pháp của bạn sẽ thất bại.

Tôi tin rằng việc cải thiện thời gian tổng thể là đủ tốt cho bạn. Trong trường hợp này, hãy đọc hướng dẫn này: http://download.oracle.com/javase/tutorial/essential/concurrency/index.html sau đó tạo nhóm chủ đề gồm 100 chủ đề và hàng đợi chứa các nguồn XML. Mỗi luồng sẽ phân tích chỉ 10 tệp sẽ mang lại lợi ích hiệu suất nghiêm trọng trong môi trường nhiều CPU.

+0

+1: Mặc dù nó có thể không cải thiện hiệu suất nhiều nếu phân tích đủ đơn giản rằng vấn đề chính là IO. –

2

Ngoài các đề xuất tốt hiện tại, có một việc khá đơn giản cần làm: sử dụng API con trỏ (XMLStreamReader), NOT API sự kiện. API sự kiện bổ sung thêm 30-50% chi phí mà không cần (chỉ IMO) làm cho việc xử lý trở nên dễ dàng hơn. Trong thực tế, nếu bạn muốn thuận tiện, tôi khuyên bạn nên sử dụng StaxMate thay thế; nó xây dựng trên đầu trang của API con trỏ mà không cần thêm chi phí đáng kể (nhiều nhất là 5-10% so với mã viết tay).

Bây giờ: Tôi giả sử bạn đã thực hiện tối ưu hóa cơ bản với Woodstox; nhưng nếu không, hãy xem "3 Simple Rules for Fast XML-processing using Stax". Đặc biệt, bạn hoàn toàn nên:

  1. Hãy chắc chắn rằng bạn chỉ tạo XMLInputFactory và XMLOutputFactory trường hợp một lần
  2. đọc Đóng và nhà văn để đảm bảo tái chế đệm (và tái sử dụng hữu ích khác) hoạt động như mong đợi.

Lý do tôi đề cập đến điều này là mặc dù chúng không có sự khác biệt về chức năng (mã hoạt động như mong đợi), chúng có thể tạo ra sự khác biệt lớn về hiệu suất; mặc dù nhiều hơn như vậy khi xử lý các tập tin nhỏ hơn.

Chạy nhiều phiên bản cũng có ý nghĩa; mặc dù thường có tối đa 1 luồng trên mỗi lõi. Tuy nhiên, bạn sẽ chỉ nhận được lợi ích miễn là lưu trữ I/O của bạn có thể hỗ trợ tốc độ như vậy; nếu đĩa là nút cổ chai này sẽ không giúp đỡ và có thể trong một số trường hợp bị tổn thương (nếu đĩa tìm kiếm cạnh tranh). Nhưng nó là giá trị một thử.

Các vấn đề liên quan