Чи справді фільтри цвітіння швидші за хеші, навіть враховуючи кеш?


16

Фільтри Bloom виглядають дуже чудово, коли ви вважаєте, що можете встановити, чи є Int набір із 99% впевненістю в постійному часі. Але так можна хешувати, з тією лише різницею, що в хеші більшу частину часу ви отримуєте доступ до пам'яті лише один раз. З фільтрами цвітіння вам потрібно отримати доступ до них ~ 7 разів за запит у абсолютно віддалених місцях , тому у вас буде кілька пропусків кешу на запит.

Я щось пропускаю?


Які зовсім далекі місця? Є лише m біт. Це, ймовірно, вписується в єдиний реєстр, або в гіршому випадку - один рядок кешу.

1
@delnan AFAIK він використовує щось близько 10 біт / елемент, ні? Отже, для декількох тисяч елементів - тобто величезних сховищ даних - це точно не поміститься в кеші. Отже, якщо ви використовуєте kхеші, у вас, ймовірно, є пропуски kкешу на прочитане. З іншого боку, хеш-таблиці гарантують, що ви отримаєте свою відповідь із 0 промахами кеша - більшість випадків зіткнення рідкісні.
MaiaVictor

У вас є k біт, період. Усі елементи впливають на однакову фіксовану кількість бітів, тому помилкова позитивна швидкість залежить від кількості записів.

Відповіді:


33

Вам не вистачає того, як обидві структури даних справляються з хеш-зіткненнями. Фільтри цвітіння не зберігають фактичних значень, тому необхідний простір - це постійний розмір позначеного масиву. Натомість, якщо ви використовуєте традиційний хеш, він намагається зберігати всі цінність, які ви йому надаєте, тому він росте з часом.

Розглянемо спрощену хеш-функцію (лише для прикладу!) f(x) = x % 2. Тепер ви вводите наступні цілі числа: 2, 3, 4, 5, 6, 7.

Стандартний хеш: задані значення будуть хешировані, і ми закінчимось великою кількістю зіткнень через f(2) = f(4) = f(6) = 0і f(3) = f(5) = f(7) = 1. Тим не менш, хеш зберігає всі ці значення, і він зможе сказати вам, що 8він не зберігається в ньому. Як це робити? Він відслідковує зіткнення та зберігає всі значення з однаковим хеш-значенням, тоді, коли ви запитуєте його, він додатково порівнює ваш запит. Тож давайте запитаємо карту для 8:, f(8) = 0то вона загляне у відро, куди ми вже вставили, 2, 4, 6і потрібно зробити 3 порівняння, щоб сказати, що 8це не було частиною вводу.

Фільтр цвітіння: зазвичай кожне вхідне значення хеширується щодо kрізних хеш-функцій. Знову ж таки, для простоти припустимо, що ми використовуємо лише функцію одиночного хешу f. Тоді нам потрібен масив з 2 значень, і коли ми стикаємося з введенням, 2це означає, що завдяки f(2) = 0значенню масиву в позиції ми встановимо 0значення 1. Те саме відбувається 4і для 6. Аналогічно, 3, 5, 7кожен вхід встановлює значення масиву 1на значення 1. Тепер ми запитуємо, чи 8був частиною введення: f(8) = 0і масив у положенні 0є 1, тож фільтр розквітання буде помилково стверджувати, що він 8був дійсно частиною введення.

Щоб зробити трохи більш реалістичним, розглянемо, що ми додамо другу функцію хешу g(x) = x % 10. З цим вхідне значення 2веде до двох хеш-значень, f(2) = 0і g(2) = 2два відповідні позиції масиву будуть встановлені на 1. Звичайно, масив тепер повинен бути як мінімум розміром 10. Але коли ми запитуємо, 8ми перевіримо масив у позиції 8через g(8) = 8, і ця позиція все ще буде 0. Ось чому додаткові хеш-функції зменшують помилкові позитиви, які ви отримаєте.

Порівняння: Фільтр цвітіння використовує kхеш-функції, що означає доступ до kвипадкових позицій масиву. Але ця цифра точна. Натомість хеш гарантує вам лише амортизований постійний час доступу, але може дегенеруватися залежно від характеру вашої хеш-функції та вхідних даних. Так це зазвичай швидше, за винятком випадків дегенерування.

Однак, коли у вас зіткнення хешу, стандартний хеш повинен буде перевірити рівність збережених значень проти значення запиту. Ця перевірка рівності може бути довільно дорогою і ніколи не відбуватиметься з фільтром цвітіння.

З точки зору простору, фільтр цвітіння є постійним, оскільки ніколи не потрібно використовувати більше пам'яті, ніж призначений масив. З іншого боку, хеш розростається динамічно і може набувати значно більших розмірів через необхідність відстежувати зіткнення значень.

Компроміс: Тепер, коли ви знаєте, що дешево, а що ні, і за яких обставин, ви зможете побачити компроміс. Фільтри цвітіння чудові, якщо ви хочете дуже швидко виявити, що значення було помічено раніше, але може жити з помилковими позитивами. З іншого боку, ви можете вибрати хеш-карту, якщо хочете гарантувати коректність ціною того, що не можете точно судити про час виконання, але ви можете приймати випадкові вироджені випадки, які можуть бути набагато повільнішими, ніж у середньому.

Так само, якщо ви перебуваєте в обмеженому середовищі пам'яті, ви можете віддати перевагу фільтрам цвітіння для гарантії їх використання.


Чудова відповідь. Це мене бентежило. Насправді кожна структура даних має найкращі випадки використання, і різний розгляд залежить від компромісу.
Річард

Це справді дуже хороше пояснення з відповідним прикладом. Тож як нам піти зі значенням "k"? Це залежить від загальної кількості значень, які ми маємо?
itsraghz

5

Застосування для фільтрів і хешів для цвітіння є чіткими і здебільшого непересічні, тому пряме порівняння не має сенсу. Крім того, це буде залежати від технічних деталей реалізації, оскільки існує багато способів вирішити хеш-зіткнення з різними компромісами.

Фільтр цвітіння може відповісти, чи є елемент набором для величезних наборів, з розумною ймовірністю, але не точно, використовуючи скромний об'єм пам'яті. Величезні, мов, трильйони елементів. Але вони ніколи не є точними. Ви можете зменшити кількість помилкових позитивів, лише використовуючи більше пам'яті або більше хеш-функцій.

З іншого боку, хеш-таблиці є точними, але в них потрібно зберігати набір. Тож для трильйонів елементів знадобиться терабайт пам'яті (і це лише американські трильйони). Вони також можуть зберігати додаткові дані для кожного елемента, який фільтри розквітання не можуть.

Тому фільтри цвітіння використовуються, коли у вас є повільний метод отримання даних для якогось учасника (який включає запит сервера, зчитування з диска тощо) великого набору (який не впишеться в пам'ять або недоцільно переносити його клієнтові або подібне) і хочуть уникнути повільної роботи об'єктів, які відсутні в наборі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.