2010-12-14 38 views
5

Tôi đã định dạng mã của tôi đang tải tệp nhị phân. Thời gian tải là khoảng 15 giây.Tìm ra kích thước tối ưu cho BufferedInputStream trong Java

Phần lớn thời gian tải của tôi đến từ các phương pháp đang tải dữ liệu nhị phân.

Tôi có đoạn code sau để tạo DataInputStream tôi:

is = new DataInputStream(
    new GZIPInputStream(
    new FileInputStream("file.bin"))); 

Và tôi đã thay đổi nó như thế này:

is = new DataInputStream(
    new BufferedInputStream(
    new GZIPInputStream(
    new FileInputStream("file.bin")))); 

Vì vậy, sau khi tôi đã làm thay đổi nhỏ này mã tải đi từ 15 giây đến 4.

Nhưng sau đó tôi thấy rằng BufferedInputStream có hai hàm tạo. Phương thức khởi tạo khác cho phép bạn xác định rõ kích thước bộ đệm.

Tôi đã có hai câu hỏi:

  1. Điều gì kích thước được chọn trong BufferedInputStream và là lý tưởng? Nếu không, làm thế nào tôi có thể tìm thấy kích thước tối ưu cho bộ đệm? Tôi có nên viết một đoạn mã nhanh để thực hiện tìm kiếm nhị phân không?
  2. Đây có phải là cách tốt nhất để tôi có thể sử dụng BufferedInputStream không? Ban đầu tôi có nó trong GZIPInputStream nhưng có lợi ích không thể bỏ qua. Tôi giả sử mã đang làm gì bây giờ là mỗi khi bộ đệm tệp cần được lấp đầy, luồng đầu vào GZIP đi qua và giải mã x byte (trong đó x là kích thước của bộ đệm). Nó có đáng để bỏ qua GZIPInputStream hoàn toàn không? Đó là chắc chắn không cần thiết, nhưng kích thước tập tin của tôi là giảm đáng kể khi sử dụng nó.

Trả lời

8

Cả GZIPInputStream và BufferedInputStream đều sử dụng bộ đệm trong. Đó là lý do tại sao sử dụng BufferedInputStream bên trong GZIPInputStream không cung cấp bất kỳ lợi ích nào. Vấn đề với GZIPInputStream là nó không đệm đầu ra mà nó tạo ra, do đó phiên bản hiện tại của bạn nhanh hơn nhiều.

Bộ đệm mặc định cho BufferedInputStream là 8kb, vì vậy bạn có thể thử và tăng hoặc giảm để xem liệu nó có giúp ích hay không. Tôi nghi ngờ rằng số lượng chính xác quan trọng nhiều, vì vậy bạn có thể chỉ cần nhân hoặc chia cho hai.

Nếu tệp nhỏ, bạn cũng có thể thử đệm hoàn toàn. Điều này sẽ cung cấp cho bạn hiệu suất tốt nhất trong lý thuyết. Bạn cũng có thể thử tăng kích thước bộ đệm của GZIPInputStream (theo mặc định 512 byte), vì điều này có thể tăng tốc độ đọc từ đĩa.

+0

Tôi đề nghị bạn thử một bộ đệm 64K cho GZIPInputStream khi đọc từ đĩa. Tôi sử dụng 1 MB, có khả năng nhiều hơn mức cần thiết. ;) –

4
  1. Đừng bận tâm với tìm kiếm nhị phân được mã hóa. Chỉ cần thử một số giá trị bằng tay và so sánh thời gian (bạn có thể thực hiện tìm kiếm nhị phân thủ công nếu bạn muốn). Bạn sẽ rất có thể thấy rằng phạm vi kích thước bộ đệm rất rộng sẽ mang đến cho bạn hiệu suất gần như tối ưu, vì vậy hãy chọn kích thước nhỏ nhất thực hiện thủ thuật.

  2. gì bạn có là đúng thứ tự: (. Nhưng không phải là đầu ra)

    is = new DataInputStream(
        new BufferedInputStream(
        new GZIPInputStream(
        new FileInputStream("file.bin")))); 
    

    Có một điểm nhỏ trong việc đưa một BufferedInputStream bên trong GZIPInputStream kể từ sau đã đệm đầu vào của nó

    Loại bỏ GZIPInputStream có thể là một chiến thắng, nhưng rất có thể sẽ gây bất lợi cho hiệu suất nếu dữ liệu phải được đọc từ đĩa và không nằm trong bộ nhớ đệm của hệ thống tệp. Lý do là đọc từ đĩa rất chậm và giải nén gzip rất nhanh. Vì vậy nó thường rẻ hơn để đọc dữ liệu ít hơn từ đĩa và giải nén nó trong bộ nhớ hơn là để đọc thêm dữ liệu từ đĩa.

+0

Cảm ơn thông tin chi tiết của bạn. – Brad

+0

Bạn được chào đón. Tôi đã chỉnh sửa câu trả lời với một chút thông tin. – NPE

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