🔬 rff: fuzzy finder
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
benches
ci
src
.gitignore
.travis.yml
Cargo.lock
Cargo.toml
LICENSE
README.md

README.md

rff

rff is a fast, simple fuzzy text selector for the terminal, with full UTF-8 support. It uses fzy's advanced scoring algorithm.

Installation

Pre-compiled binaries are available, starting with version 0.3.0.

If you have a Rust toolchain installed, you can also build rff from source via Cargo:

$ cargo install rff

Additionally, you can tell rustc to build for your specific CPU architecture, for a possible minor speedup:

$ RUSTFLAGS="-C target-cpu=native" cargo install rff

Usage

rff is a drop-in replacement for other fuzzy finders such as fzy or selecta.

For some examples of how these sorts of tools can be used, see selecta's examples.

Benchmarks

Both fzy and rff have a --benchmark mode, which runs the matching/scoring loop 100 times, without printing anything. This helps minimize impact of startup cost and I/O, and better demonstrate actual matching/scoring speed.

To ensure a large enough corpus, such that multithreaded optimizations can take place, these tests were run against a listing of files in the Linux kernel source tree.

The results indicate that in general, rff is slightly slower that fzy on Linux, and significantly faster on macOS. However, in real use, both of these tool will be more than fast enough for most projects. We're testing against the entire Linux kernel, in an arbitrary benchmark mode, after all!

A tradeoff is that rff supports UTF-8 characters, both in input and search terms, while fzy focuses on ASCII, though there are plans to support wide characters eventually.

The hyperfine tool was used to generate these results.

This benchmark was run on on a fresh 20-core Linode instance running Ubuntu 16.04 LTS:

$ find ~/dev/linux -type f > files

$ hyperfine --warmup 5 'fzy -e drivers --benchmark < files' 'rff -s drivers --benchmark < files'
Benchmark #1: fzy -e drivers --benchmark < files

  Time (mean ± σ):     423.9 ms ±   7.8 ms

  Range (min … max):   407.7 ms … 432.9 ms

Benchmark #2: rff -s drivers --benchmark < files

  Time (mean ± σ):     529.7 ms ±   7.2 ms

  Range (min … max):   512.2 ms … 536.4 ms

Interestingly, the macOS implementation of tolower(3) appears to be poorly optimized, resulting in much slower scoring for fzy:

λ find ~/dev/linux -type f > files

$ hyperfine --warmup 5 'fzy -e drivers --benchmark < files' 'rff -s drivers --benchmark < files'
Benchmark #1: fzy -e drivers --benchmark < files

  Time (mean ± σ):     1.764 s ± 0.337 s

  Range (min … max):   1.653 s … 2.722 s

Benchmark #2: rff -s drivers --benchmark < files

  Time (mean ± σ):     1.019 s ± 0.004 s

  Range (min … max):   1.015 s … 1.027 s

If you've got any ideas for how rff can get even faster, please reach out and let me know! This is an area of programming that I'm not entirely familiar with, and building this tool has been a fun learning experience!