2009-06-26 47 views
9

Tôi đang cố gắng viết một số ứng dụng, thực hiện phân tích dữ liệu, được lưu trữ trong các tệp XML khá lớn (từ 10 đến 800MB). Mỗi bộ dữ liệu được lưu trữ dưới dạng một thẻ duy nhất, với dữ liệu cụ thể được chỉ định làm attrobutes. Tôi hiện đang saxParse từ HaXml, và tôi không hài lòng với việc sử dụng bộ nhớ trong khi làm việc với nó. Khi phân tích cú pháp tệp 15Mb XML, nó tiêu thụ hơn 1Gb bộ nhớ, mặc dù tôi đã cố gắng không lưu trữ dữ liệu trong danh sách và xử lý nó ngay lập tức. Tôi sử dụng đoạn mã sau:Trình phân tích cú pháp XML nào cho Haskell?

importOneFile file proc ioproc = do 
    xml <- readFile file 
    let (sxs, res) = saxParse file $ stripUnicodeBOM xml 
    case res of 
     Just str -> putStrLn $ "Error: " ++ str; 
     Nothing -> forM_ sxs (ioproc . proc . (extractAttrs "row")) 

nơi 'proc' - thủ tục, mà thực hiện chuyển đổi dữ liệu từ thuộc tính vào thu âm, và 'ioproc' - thủ tục, mà thực hiện một số hành động IO - đầu ra cho màn hình, lưu trữ trong cơ sở dữ liệu, v.v.

Làm cách nào để giảm mức tiêu thụ bộ nhớ trong quá trình phân tích cú pháp XML? Có nên chuyển sang trình phân tích cú pháp XML khác không?

Cập nhật: và trình phân tích cú pháp nào hỗ trợ cho các mã hóa đầu vào khác nhau - utf-8, utf-16, utf-32, v.v ...?

Trả lời

4

Nếu bạn sẵn sàng cho rằng đầu vào của bạn hợp lệ, hãy xem xét TagSoup hoặc Text.XML.Light từ những người Galois.

Những mất chuỗi như là đầu vào, vì vậy bạn có thể (gián tiếp) họ ăn bất cứ thứ gì Data.Encoding hiểu, cụ thể là

  • ASCII
  • UTF8
  • UTF16
  • UTF32
  • KOI8R
  • KOI8U
  • ISO88591
  • GB18030
  • BootString
  • ISO88592
  • ISO88593
  • ISO88594
  • ISO88595
  • ISO88596
  • ISO88597
  • ISO88598
  • ISO88599
  • ISO885910
  • ISO885911
  • ISO885913
  • ISO885914
  • ISO885915
  • ISO885916
  • CP1250
  • CP1251
  • CP1252
  • CP1253
  • CP1254
  • CP1255
  • CP1256
  • CP1257
  • CP1258
  • MacOSRoman
  • JISX0201
  • JISX0208
  • ISO2022JP
  • JISX0212
3

Tôi không phải là chuyên gia Haskell, nhưng những gì bạn đang chạy vào âm thanh như rò rỉ không gian cổ điển (ví dụ: tình huống trong đó đánh giá lười biếng của Haskell khiến nó đặt nhiều bộ nhớ hơn mức cần thiết). Bạn có thể giải quyết nó bằng cách buộc độ chặt chẽ trên đầu ra saxParse của bạn.

Ngoài ra còn có một chương tốt về hồ sơ và tối ưu hóa trong Real World Haskell.

EDIT: Tìm thấy một nguồn lực tốt trên profiling/Phát hiện tắc nghẽn here.

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