2011-07-28 50 views
14

Tôi có ứng dụng máy chủ java tải xuống tệp CSV và phân tích cú pháp đó. Việc phân tích cú pháp có thể mất từ ​​5 đến 45 phút, và xảy ra mỗi giờ. Phương pháp này là một nút cổ chai của ứng dụng vì vậy nó không phải là tối ưu hóa sớm. Mã cho đến thời điểm này:Phân tích cú pháp CSV nhanh

 client.executeMethod(method); 
     InputStream in = method.getResponseBodyAsStream(); // this is http stream 

     String line; 
     String[] record; 

     reader = new BufferedReader(new InputStreamReader(in), 65536); 

     try { 
      // read the header line 
      line = reader.readLine(); 
      // some code 
      while ((line = reader.readLine()) != null) { 
       // more code 

       line = line.replaceAll("\"\"", "\"NULL\""); 

       // Now remove all of the quotes 
       line = line.replaceAll("\"", "");  


       if (!line.startsWith("ERROR"){ 
        //bla bla 
        continue; 
       } 

       record = line.split(","); 
       //more error handling 
       // build the object and put it in HashMap 
     } 
     //exceptions handling, closing connection and reader 

Có thư viện nào có thể giúp tôi tăng tốc không? Tôi có thể cải thiện mã hiện tại không?

+2

Tệp lớn như thế nào? Và bạn đã thử định dạng mã của mình chưa? Điều này sẽ cung cấp cho bạn nút cổ chai của bạn và một ý tưởng rõ ràng nơi để cải thiện. Tôi sẽ không ngạc nhiên nếu mạng của bạn là vấn đề chính. Ngoài ra, hãy xem http://commons.apache.org/sandbox/csv/ thay vì tự mình xây dựng trình phân tích cú pháp. – joostschouten

+0

Tôi đang lập hồ sơ ngay bây giờ và tôi biết rằng phần lớn thời gian là do kết nối mạng. Tôi muốn cải thiện phân tích cú pháp trước hết bởi vì với mạng tôi cần thay đổi kiến ​​trúc. (Ước tính của tôi là phân tích cú pháp nhanh hơn có thể cải thiện thời gian tải lên 10-15%). –

+0

Nghe có vẻ công bằng. Do sử dụng một bộ phân tích cú pháp csv vì chúng được tối ưu hóa và bạn đang bị ràng buộc để chạy vào thoát và i18n vấn đề xuống con đường mà bạn không muốn lo lắng về. Chúc may mắn. – joostschouten

Trả lời

18

Apache Commons CSV

Bạn đã xem Apache Commons CSV chưa?

Caveat Ngày Sử dụng split

Một điều cần ghi nhớ là split chỉ trả lại một cái nhìn của dữ liệu, có nghĩa là các đối tượng gốc line không đủ điều kiện cho thu gom rác thải trong khi có một tham chiếu đến bất kỳ của nó lượt xem. Có lẽ làm một bản sao phòng thủ sẽ giúp đỡ? (Java bug report)

+0

+1 cho lỗi và tôi sẽ thử apache. –

13

opencsv

Hãy xem opencsv.

Bài đăng trên blog này, opencsv is an easy CSV parser, có ví dụ về cách sử dụng.

+0

Xem nhận xét về [câu trả lời anh chị em tương tự] (http://stackoverflow.com/a/6857291/642706). –

2

opencsv

Bạn nên xem OpenCSV. Tôi hy vọng rằng họ có tối ưu hóa hiệu suất.

+0

Chúng tôi có kinh nghiệm rất xấu với opencsv. chúng tôi tìm thấy nó là cả chậm và buggy. đã kết thúc lãng phí nửa ngày, và thay thế nó hoàn toàn. – Guy

+0

ok ... bạn có thể muốn thêm các chi tiết khác để làm cho thông tin này có liên quan. Bạn có vấn đề gì? Bạn đã sử dụng phiên bản nào? Bạn đã chọn khung công tác nào khác? Tôi chỉ tự hỏi vì tôi đã nhìn thấy nó trong nhiều hơn một dự án mà nó đã làm một công việc tốt. – Kai

+0

Vấn đề chính là nó trả lại số trường sai (tức là tôi nhận được một chuỗi trường 2 [] trên một dòng 10 trường) cho một số dòng nhất định. Tôi không bao giờ hiểu tại sao nó lại xảy ra, nhưng tôi đoán nó liên quan đến việc phân tích cú pháp utf-8 xấu. Tôi đã thay thế nó bằng dòng đọc riêng của mình, String.split mỗi dòng (tôi nhận ra có những cân nhắc về bộ nhớ ở đây), kết quả chạy nhanh hơn từ 15% -30%. Tôi đã sử dụng opencs v2.3 (java) – Guy

5

Ngoài các đề xuất được đưa ra ở trên, tôi nghĩ bạn có thể thử cải thiện mã của mình bằng cách sử dụng một số luồng và đồng thời.

Sau đây là phân tích ngắn gọn và giải pháp đề nghị

  1. Từ mã có vẻ như bạn đang đọc dữ liệu qua mạng (có thể nhất apache-chung-httpclient lib).
  2. Bạn cần đảm bảo rằng nút cổ chai mà bạn đang nói không có trong quá trình truyền dữ liệu qua mạng.
  3. Một cách để xem chỉ là đổ dữ liệu vào một số tệp (không phân tích cú pháp) và xem nó mất bao nhiêu. Điều này sẽ cung cấp cho bạn một ý tưởng bao nhiêu thời gian thực sự được chi tiêu trong phân tích cú pháp (khi so sánh với quan sát hiện tại).
  4. Bây giờ hãy xem cách sử dụng gói java.util.concurrent. Một số liên kết mà bạn có thể sử dụng là (1, 2)
  5. Những gì bạn làm là các tác vụ mà bạn đang thực hiện trong vòng lặp có thể được thực hiện trong một chuỗi.
  6. Sử dụng luồng và đồng thời sẽ cải thiện đáng kể hiệu suất của bạn.

Mặc dù giải pháp liên quan đến một số nỗ lực nhưng cuối cùng điều này sẽ giúp ích cho bạn.

+0

nếu nút cổ chai được chuyển qua mạng, bạn nên cân nhắc chỉ định tiêu đề gzip –

5

Sự cố mã của bạn là mã của bạn đang sử dụng replaceAll và chia nhỏ hoạt động rất tốn kém. Bạn chắc chắn nên cân nhắc sử dụng trình phân tích cú pháp csv/trình đọc sẽ thực hiện phân tích cú pháp một lần.

Có một điểm chuẩn trên github

https://github.com/uniVocity/csv-parsers-comparison

rằng không may là chạy dưới java 6. Số là hơi khác nhau dưới java 7 và 8. Tôi đang cố gắng để có thêm dữ liệu chi tiết cho tập tin khác nhau kích thước nhưng đó là công việc cơ bản dở dang

thấy https://github.com/arnaudroger/csv-parsers-comparison

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