Là bộ lọc nở thực sự nhanh hơn băm, thậm chí lấy bộ nhớ cache tài khoản?


15

Bộ lọc Bloom trông thực sự tuyệt vời khi bạn xem xét bạn có thể xác định xem một Int có trong một bộ với độ chắc chắn 99% trong thời gian không đổi. Nhưng như vậy có thể băm, với sự khác biệt duy nhất là, trong một hàm băm, hầu hết thời gian bạn chỉ truy cập vào bộ nhớ. Với các bộ lọc nở, bạn cần truy cập chúng ~ 7 lần cho mỗi yêu cầu ở những nơi hoàn toàn xa , do đó bạn sẽ có một vài lỗi nhớ cache cho mỗi yêu cầu.

Tui bỏ lỡ điều gì vậy?


Những nơi hoàn toàn xa xôi? Chỉ có m bit. Điều đó có thể phù hợp với một thanh ghi duy nhất, hoặc tệ nhất là một dòng bộ đệm duy nhất.

1
@delnan AFAIK nó sử dụng khoảng 10 bit / phần tử, phải không? Vì vậy, đối với hàng ngàn phần tử - tức là kho dữ liệu khổng lồ - nó chắc chắn sẽ không phù hợp với bộ đệm. Vì vậy, nếu bạn đang sử dụng kbăm, có lẽ bạn đang bị klỗi cache trong mỗi lần đọc. Mặt khác, các bảng băm đảm bảo rằng bạn sẽ có câu trả lời với 0 bộ nhớ cache hầu hết thời gian - dù sao thì các va chạm rất hiếm.
MaiaVictor

Bạn có k bit, thời gian. Tất cả các yếu tố ảnh hưởng đến cùng một số bit cố định, đó là lý do tại sao tỷ lệ dương sai phụ thuộc vào số lượng mục nhập.

Câu trả lời:


31

Bạn đang thiếu cách hai cấu trúc dữ liệu xử lý các va chạm băm. Các bộ lọc nở không lưu trữ các giá trị thực tế, vì vậy không gian cần thiết là kích thước không đổi của mảng được chỉ định. Thay vào đó nếu bạn sử dụng hàm băm truyền thống, nó sẽ cố gắng lưu trữ tất cả các giá trị bạn cung cấp cho nó, để nó phát triển theo thời gian.

Hãy xem xét một hàm băm đơn giản hóa (chỉ vì một ví dụ!) f(x) = x % 2. Bây giờ bạn nhập các số nguyên sau : 2, 3, 4, 5, 6, 7.

Hash chuẩn: các giá trị đã cho sẽ được băm và chúng tôi kết thúc với rất nhiều va chạm do f(2) = f(4) = f(6) = 0f(3) = f(5) = f(7) = 1. Tuy nhiên, hàm băm lưu trữ tất cả các giá trị này và nó sẽ có thể cho bạn biết rằng 8nó không được lưu trữ trong đó. sao làm được vậy? Nó theo dõi các va chạm và lưu trữ tất cả các giá trị có cùng giá trị băm, sau đó khi bạn truy vấn nó, nó sẽ so sánh truy vấn của bạn. Vì vậy, hãy truy vấn bản đồ cho 8: f(8) = 0, vì vậy nó sẽ xem xét một nhóm mà chúng tôi đã chèn 2, 4, 6và cần thực hiện 3 so sánh để cho bạn biết rằng đó 8không phải là một phần của đầu vào.

Bộ lọc Bloom: Thông thường, mỗi giá trị đầu vào được băm đối với kcác hàm băm khác nhau. Một lần nữa, để đơn giản, hãy giả sử rằng chúng ta chỉ sử dụng hàm băm duy nhất f. Chúng ta cần một mảng gồm 2 giá trị sau đó và khi chúng ta gặp đầu vào, 2điều đó có nghĩa là do f(2) = 0chúng ta đặt giá trị mảng ở vị trí 0thành giá trị 1. Điều tương tự xảy ra cho 46. Tương tự, 3, 5, 7mỗi đầu vào đặt vị trí mảng 1thành giá trị 1. Bây giờ chúng tôi truy vấn nếu 8là một phần của đầu vào: f(8) = 0và mảng ở vị trí 01, vì vậy bộ lọc nở sẽ tuyên bố sai đó 8thực sự là một phần của đầu vào.

Để thực tế hơn một chút, hãy xem xét rằng chúng ta thêm hàm băm thứ hai g(x) = x % 10. Cùng với đó, giá trị đầu vào 2dẫn đến hai giá trị băm f(2) = 0g(2) = 2và hai vị trí mảng tương ứng sẽ được thiết lập để 1. Tất nhiên, mảng bây giờ nên có kích thước tối thiểu 10. Nhưng khi chúng tôi truy vấn, 8chúng tôi sẽ kiểm tra mảng tại vị trí 8do g(8) = 8và vị trí đó sẽ vẫn còn 0. Đó là lý do tại sao các hàm băm bổ sung làm giảm các giá trị dương bạn sẽ nhận được.

So sánh: Bộ lọc nở sử dụng kcác hàm băm có nghĩa là lên đến kcác vị trí mảng ngẫu nhiên đang được truy cập. Nhưng con số đó là chính xác. Thay vào đó, hàm băm chỉ đảm bảo cho bạn thời gian truy cập liên tục được khấu hao, nhưng có thể hủy tạo tùy thuộc vào bản chất của hàm băm và dữ liệu đầu vào của bạn. Vì vậy, nó thường nhanh hơn, ngoại trừ các trường hợp khử.

Tuy nhiên, một khi bạn có xung đột băm, hàm băm tiêu chuẩn sẽ phải kiểm tra sự bằng nhau của các giá trị được lưu trữ so với giá trị truy vấn. Việc kiểm tra tính bằng này có thể tốn kém tùy ý và sẽ không bao giờ xảy ra với bộ lọc nở.

Về không gian, bộ lọc nở là không đổi, vì không bao giờ có nhu cầu sử dụng nhiều bộ nhớ hơn mảng được chỉ định. Mặt khác, hàm băm phát triển linh hoạt và có thể lớn hơn nhiều do phải theo dõi các giá trị bị va chạm.

Trao đổi: Bây giờ bạn biết cái gì rẻ và cái gì không và trong hoàn cảnh nào, bạn sẽ có thể thấy sự đánh đổi. Bộ lọc Bloom rất tuyệt nếu bạn muốn nhanh chóng phát hiện ra rằng một giá trị đã được nhìn thấy trước đó, nhưng có thể sống với dương tính giả. Mặt khác, bạn có thể chọn bản đồ băm nếu bạn muốn đảm bảo tính chính xác ở mức giá không thể đánh giá chính xác thời gian chạy của bạn, nhưng có thể chấp nhận các trường hợp thoái hóa thỉnh thoảng có thể chậm hơn nhiều so với mức trung bình.

Tương tự, nếu bạn ở trong môi trường bộ nhớ hạn chế, bạn có thể muốn sử dụng các bộ lọc nở để đảm bảo sử dụng bộ nhớ của chúng.


Câu trả lời chính xác. Đây là những gì tôi đã nhầm lẫn. Trên thực tế, mọi cấu trúc dữ liệu đều có các trường hợp sử dụng tốt nhất và việc xem xét khác nhau phụ thuộc vào sự đánh đổi.
Richard

Đó thực sự là một lời giải thích rất tốt với một ví dụ phù hợp. Vậy làm thế nào để chúng ta đi với giá trị 'k'? Có phụ thuộc vào tổng số giá trị những gì chúng ta có?
itraghz

5

Các trường hợp sử dụng cho bộ lọc nở và băm là khác biệt và chủ yếu là rời rạc, do đó so sánh trực tiếp không có ý nghĩa. Bên cạnh đó, nó sẽ phụ thuộc vào các chi tiết kỹ thuật của việc triển khai vì có nhiều cách để xử lý các va chạm băm với các sự đánh đổi khác nhau.

Bộ lọc nở có thể trả lời liệu phần tử có trong một tập hợp cho các tập lớn hay không , với xác suất hợp lý, nhưng không chính xác, sử dụng lượng bộ nhớ khiêm tốn. Lớn, như, hàng nghìn tỷ yếu tố. Nhưng chúng không bao giờ chính xác. Bạn chỉ có thể giảm số lượng dương tính giả bằng cách sử dụng nhiều bộ nhớ hơn hoặc nhiều hàm băm hơn.

Mặt khác, bảng băm là chính xác, nhưng họ cần lưu trữ tập hợp. Vì vậy, hàng nghìn tỷ yếu tố sẽ cần đến terrabyte bộ nhớ (và đó chỉ là hàng nghìn tỷ của người Mỹ). Họ cũng có thể lưu trữ dữ liệu bổ sung cho từng thành phần mà bộ lọc nở không thể.

Vì vậy, các bộ lọc nở được sử dụng khi bạn có phương pháp lấy dữ liệu chậm cho một số thành viên (liên quan đến máy chủ truy vấn, đọc từ đĩa và như vậy) của một bộ lớn (không phù hợp trong bộ nhớ hoặc không thực tế để chuyển nó sang máy khách hoặc như vậy) và muốn tránh chạy hoạt động chậm cho các đối tượng không có trong tập hợp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.