FastFilter

December 30, 2024 ยท View on GitHub

NuGet License

Description

FastFilter is a C# implementation of a few different Bloom filters with focus on high performance. It contains the following Bloom filter implementations:

  • Bloom filter
  • Register Blocked Bloom filter
  • BinaryFuse filter

Features

  • Add()
  • Contains()

Example

static void Main()
{
    int[] data = [1, 42, 30, 481, 58];
    BinaryFuse8Filter<int> fuse = new BinaryFuse8Filter<int>(data);

    Console.WriteLine("Does it contain 42? " + (fuse.Contains(42) ? "Maybe" : "No"));
    Console.WriteLine("Does it contain 50? " + (fuse.Contains(50) ? "Maybe" : "No"));
}

Output:

Does it contain 42? Maybe
Does it contain 50? No

The reason it says "Maybe" is because Bloom filters can have false positives, but never false negatives. If it says "No", it is guaranteed that the item is not in the filter.

Benchmarks

MethodFilterMeanErrorStdDev
AddBinaryFuse16FilterNANANA
AddBinaryFuse8FilterNANANA
AddBlockedBloomFilter1.017 ns0.0442 ns0.0196 ns
AddHashSetBloomFilter3.262 ns0.0845 ns0.0559 ns
AddBloomFilter4.689 ns0.1011 ns0.0156 ns
ContainsBlockedBloomFilter1.755 ns0.0459 ns0.0119 ns
ContainsBinaryFuse16Filter2.274 ns0.0661 ns0.0294 ns
ContainsHashSetBloomFilter2.575 ns0.0372 ns0.0058 ns
ContainsBinaryFuse8Filter2.632 ns0.0690 ns0.0107 ns
ContainsBloomFilter4.531 ns0.0994 ns0.0441 ns

HashSetBloomFilter is a Bloom filter that uses a HashSet as a backing store. It is only included for comparison, since .NET does not natively have a Bloom filter. BinaryFuse filters give NA for Add() because they are immutable once constructed.

For retaining 1000 64bit integers (8000 bytes), the memory usage is as follows:

FilterMemoryFalse-positives
BloomFilter1008 bytes2.144%
BlockedBloomFilter1320 bytes3.432%
BinaryFuse8Filter1416 bytes0.387%
BinaryFuse16Filter2824 bytes0.001%
HashSetBloomFilter30920 bytes0%

It is possible to tweak the false positive percentage for BloomFilter and BlockedBloomFilter. Lower false positive percent means more memory usage.