2013-06-17 25 views
9

Sự tò mò và hiệu quả là những lý do cho câu hỏi này. Tôi đang ở một tình huống mà tôi đang tạo ra nhiều HashSets mới sau vòng nhất định chạy:Hiệu quả bộ nhớ của việc xóa một HashSet so với việc tạo một HashSet mới

Các HashSet hiện được khai báo như vậy ở phía trên cùng của lớp:

private Set<String> failedTests; 

Rồi sau này trong mã, tôi chỉ tạo một failTests mới HashSet bất cứ khi nào tôi chạy lại các thử nghiệm:

failedTests = new HashSet<String>(16384); 

Tôi thực hiện việc này lặp đi lặp lại, tùy thuộc vào kích thước của phép thử. Tôi hy vọng bộ thu gom rác sẽ xử lý hiệu quả nhất dữ liệu cũ. Nhưng, tôi biết một tùy chọn khác sẽ là tạo HashSet ban đầu ngay từ đầu:

private Set<String> failedTests = new HashSet<String>(16384); 

và sau đó xóa HashSet mỗi lần qua vòng lặp.

failedTests.clear(); 

Câu hỏi của tôi là cách hiệu quả nhất để làm điều này về chi phí, v.v ... là gì? Tôi không biết chức năng rõ ràng() đang làm gì bên trong - là nó làm điều tương tự, gửi dữ liệu cũ đến bộ sưu tập rác, hay nó đang làm một cái gì đó thậm chí còn hiệu quả hơn? Ngoài ra, tôi cung cấp cho HashSet một dung lượng lớn dung lượng ban đầu, nhưng nếu một bài kiểm tra yêu cầu nhiều hơn 2^14 phần tử, thì hàm .clear() có thể tái khởi tạo HashSet thành 16384 không?

Để thêm, tôi đã tìm thấy source code to clear() here. Vì vậy, nó ít nhất là một hoạt động O (n) của trường hợp xấu nhất.

Sử dụng chức năng rõ ràng, tôi đã thực hiện một quá trình thử nghiệm hoàn tất sau 565 giây. Sử dụng GC để xử lý nó, kiểm tra kết thúc sau 506 giây.

Nhưng không phải là điểm chuẩn hoàn hảo vì có các yếu tố bên ngoài khác như giao tiếp với hệ thống tệp của máy tính và mạng. Nhưng một phút đầy đủ cảm thấy khá tốt thực sự. Có ai đề nghị một hệ thống hồ sơ cụ thể mà sẽ làm việc trên mức độ dòng/phương pháp? (Tôi đang sử dụng Eclipse Indigo)

+0

Bạn đã thử điểm chuẩn chưa? – rob

+0

Bạn có bất kỳ biện pháp nào về cách tạo * nhiều * bộ mới? Bạn có thực sự kiểm tra hành vi của ứng dụng của bạn không? Đó là trường hợp của câu hỏi * bộ nhớ so với hiệu suất * thường dẫn đến tối ưu hóa sớm. Là một cơ sở, bạn có thể tạo một 'HashSet' mới, cho phép GC thực hiện công việc của mình và làm một chút lược tả để xem thời gian thực trước khi đáng lo ngại. Sau khi tất cả, phương pháp 'clear' liên quan đến một iteration, nulling references và cho phép GC thực hiện công việc của mình. – Gamb

+0

có thể trùng lặp của [Cách nhanh nhất để tạo lại ArrayList trong vòng lặp for] (http://stackoverflow.com/questions/11740013/fastest-way-to-recreate-the-arraylist-in-a-for-loop): 'new' thường nhanh hơn' clear'. – assylias

Trả lời

6

Tôi không biết những gì() chức năng rõ ràng đang làm bên

Người ta gọi phương thức clear() của HashMap bảng mà nó được sử dụng trong nội bộ. Trong HashMap phương pháp clear() được định nghĩa như sau:

public void clear() { 
    modCount++; 
    Entry[] tab = table; 
    for (int i = 0; i < tab.length; i++) 
     tab[i] = null; 
    size = 0; 
} 

là nó làm điều tương tự, gửi dữ liệu cũ sang thu gom rác thải , hoặc là nó làm một cái gì đó thậm chí hiệu quả hơn?

tab[i] = null chỉ ra rằng dữ liệu cũ đủ điều kiện để thu thập rác.

Ngoài ra, tôi đang đưa ra các HashSet một đệm lớn công suất ban đầu, nhưng nếu xét nghiệm đòi hỏi nhiều hơn 2^14 nguyên tố, sẽ là .clear() chức năng lại nhanh chóng các HashSet đến 16384?

Không, không.

là cách hiệu quả nhất để thực hiện việc này về mặt chi phí, v.v.

Tôi đoán, Bộ thu gom rác Java biết cách thực hiện công việc của mình theo cách hiệu quả nhất. Vì vậy, hãy để người thu gom rác thải xử lý việc này. Vì vậy, tôi muốn tạo ra một thất bại mới HashSet mỗi lần nó là cần thiết.

+2

Các đối tượng lớn đi thẳng vào không gian đã thuê, vì vậy tốn kém hơn cho GC hơn là GC các đối tượng nhỏ hơn trong thế hệ vườn ươm. Tuy nhiên, chi phí này so với chi phí lặp qua tất cả 16000 yếu tố của mảng sao lưu. –

4

tạo lại HashSet hiệu quả hơn.

1) nếu công suất HashSet lớn trên 16.384 rõ ràng sẽ không reset nó cho công suất ban đầu

2) HashSet mới (16384) tạo ra một Entry mới [16384] mảng, nó là một hoạt động, đó là hiệu quả hơn so với các yếu tố nulling từng cái một như rõ ràng không

for (int i = 0; i < table.length; i++) 
    tab[i] = null; 
Các vấn đề liên quan