Filter Bloom terlihat sangat hebat ketika Anda mempertimbangkan Anda dapat menentukan apakah Int berada di set dengan 99% kepastian dalam waktu yang konstan. Tapi begitu juga hash, dengan satu-satunya perbedaan itu, dalam hash, sebagian besar waktu Anda mengakses memori hanya sekali. Dengan filter bloom, Anda perlu mengaksesnya ~ 7 kali per permintaan di tempat yang sangat jauh , sehingga Anda akan memiliki beberapa cache yang hilang per permintaan.
Apakah saya melewatkan sesuatu?
data-structures
Viktor Maia
sumber
sumber
k
hash, Anda mungkin mengalamik
kesalahan cache per baca. Tabel hash di sisi lain menjamin bahwa Anda akan mendapatkan jawaban Anda dengan 0 cache paling sering hilang - tabrakan jarang terjadi.Jawaban:
Anda kehilangan bagaimana kedua struktur data berurusan dengan benturan hash. Filter bloom tidak menyimpan nilai aktual, sehingga ruang yang dibutuhkan adalah ukuran konstan dari array yang ditunjuk. Alih-alih jika Anda menggunakan hash tradisional, ia mencoba untuk menyimpan semua nilai yang Anda berikan, sehingga tumbuh seiring waktu.
Pertimbangkan fungsi hash yang disederhanakan (hanya untuk contoh saja!)
f(x) = x % 2
. Sekarang Anda masukan bilangan bulat berikut:2, 3, 4, 5, 6, 7
.Standard Hash: nilai yang diberikan akan di-hash, dan kita berakhir dengan banyak tabrakan karena
f(2) = f(4) = f(6) = 0
danf(3) = f(5) = f(7) = 1
. Namun demikian, hash menyimpan semua nilai-nilai ini dan itu akan dapat memberi tahu Anda bahwa8
tidak disimpan di dalamnya. Bagaimana cara melakukannya? Ini melacak tabrakan dan menyimpan semua nilai dengan nilai hash yang sama, kemudian ketika Anda menanyakannya, itu juga membandingkan permintaan Anda. Jadi mari kita query peta untuk8
:,f(8) = 0
jadi itu akan melihat ke ember di mana kita telah memasukkan2, 4, 6
dan perlu membuat 3 perbandingan untuk memberi tahu Anda bahwa8
itu bukan bagian dari input.Filter Bloom: Biasanya, setiap nilai input hash terhadap
k
fungsi hash yang berbeda. Sekali lagi, untuk kesederhanaan, anggap saja kita hanya menggunakan fungsi hash tunggalf
. Kita memerlukan array 2 nilai lalu dan ketika kita menemukan input2
itu berarti bahwa karenaf(2) = 0
kita mengatur nilai array pada posisi0
ke nilai1
. Hal yang sama terjadi untuk4
dan6
. Demikian pula, input3, 5, 7
masing-masing mengatur posisi array1
ke nilai1
. Sekarang kita kueri apakah8
itu bagian dari input:f(8) = 0
dan array pada posisi0
adalah1
, sehingga filter bloom akan mengklaim bahwa8
itu memang bagian dari input.Agar lebih realistis, mari kita tambahkan fungsi hash kedua
g(x) = x % 10
. Dengan itu, nilai input2
mengarah ke dua nilai hashf(2) = 0
dang(2) = 2
dan dua posisi array yang sesuai akan diatur ke1
. Tentu saja, array sekarang harus berukuran paling tidak10
. Tetapi ketika kami meminta8
kami akan memeriksa array pada posisi8
karenag(8) = 8
, dan posisi itu akan tetap0
. Itu sebabnya fungsi hash tambahan mengurangi false positive yang akan Anda dapatkan.Perbandingan: Filter bloom menggunakan
k
fungsi hash yang berarti hinggak
posisi array acak sedang diakses. Namun angka itu tepat. Sebaliknya, hash hanya menjamin Anda waktu akses konstan yang diamortisasi, tetapi dapat membatalkan pembuatan tergantung pada sifat fungsi hash Anda dan memasukkan data. Jadi biasanya lebih cepat, kecuali untuk kasus yang dihasilkan.Namun, setelah Anda memiliki tabrakan hash hash standar harus memeriksa kesetaraan nilai yang disimpan terhadap nilai kueri. Pemeriksaan kesetaraan ini mungkin mahal dan tidak akan pernah terjadi dengan filter bloom.
Dalam hal ruang, filter bloom konstan, karena tidak pernah perlu menggunakan lebih banyak memori daripada array yang ditunjuk. Di sisi lain, hash tumbuh secara dinamis dan mungkin menjadi jauh lebih besar karena harus melacak nilai-nilai yang bertabrakan.
Trade-off: Sekarang Anda tahu apa yang murah dan apa yang tidak dan dalam situasi apa, Anda harus dapat melihat trade-off. Filter Bloom sangat bagus jika Anda ingin mendeteksi dengan cepat bahwa suatu nilai telah terlihat sebelumnya, tetapi dapat hidup dengan positif palsu. Di sisi lain, Anda dapat memilih peta hash jika Anda ingin benar kebenarannya dengan harga tidak bisa menilai secara tepat runtime Anda, tetapi dapat menerima kasus-kasus degenerasi sesekali yang mungkin jauh lebih lambat daripada rata-rata.
Demikian pula, jika Anda berada di lingkungan memori terbatas, Anda mungkin ingin memilih filter bloom untuk jaminan penggunaan memori mereka.
sumber
Kasus penggunaan untuk filter mekar dan hash berbeda dan sebagian besar terpisah, sehingga perbandingan langsung tidak masuk akal. Selain itu akan tergantung pada detail teknis dari implementasi karena ada banyak cara untuk menangani tabrakan hash dengan trade-off yang berbeda.
Filter bloom dapat menjawab apakah elemen dalam set untuk set besar , dengan probabilitas yang masuk akal, tetapi tidak tepat, menggunakan jumlah memori yang sederhana. Besar, seperti, triliunan elemen. Tetapi mereka tidak pernah tepat. Anda hanya dapat mengurangi jumlah positif palsu dengan menggunakan lebih banyak memori atau lebih banyak fungsi hash.
Di sisi lain tabel hash tepat, tetapi mereka perlu menyimpan set. Jadi triliunan elemen akan membutuhkan memori terrabytes (dan itu hanya triliunan Amerika). Mereka juga dapat menyimpan data tambahan untuk setiap elemen, yang tidak bisa disaring oleh filter bloom.
Jadi filter bloom digunakan ketika Anda memiliki metode lambat untuk mendapatkan data untuk beberapa anggota (yang melibatkan server query, membaca dari disk dan semacamnya) dari satu set besar (yang tidak sesuai dengan memori atau tidak praktis untuk mentransfernya ke klien atau semacamnya) dan ingin menghindari operasi yang lambat untuk objek yang tidak diatur.
sumber