bfs shallow target search vs findalias find=bfs preserves all scriptsTraversal Architecture & Design Philosophy
DFS vs BFS
While both tools blow standard single-threaded GNU find out of the water, they are optimized for diametrically opposite traversal philosophies:
Built on Rust's ignore::WalkParallel engine. Uses a multi-threaded work-stealing deque where worker threads dive down independent directory subtrees.
- Stack-Bounded Memory: Memory footprint is strictly $O(\text{threads} \times \text{depth})$ (~5–20 MB).
- Developer Defaults: Automatically excludes
.gitignore,.git/, and hidden files. - SIMD Regex: Blazing-fast pattern filtering across massive warm-cache repositories.
Custom Asynchronous I/O Queue (ioq.c) with lock-free MPMC ring buffers and a priority file descriptor cache (dircache.c).
- Instant Shallow Discovery: Inspects depth $k$ entirely before descending to depth $k+1$.
- 100% POSIX/GNU/BSD Parity: Drop-in replacement for all standard
findscripts and expressions. openat()Cache: Avoids redundant path lookups and gracefully evicts FDs to preventEMFILE.
Performance Benchmarks
Empirical Data (7.6M Files Dataset)Relative Speedup vs GNU find (Higher is Better)
Memory Consumption (MB, Lower is Better)
| Workload Scenario | GNU find |
fd (Parallel DFS) |
bfs (Breadth-First) |
Winner & Why |
|---|---|---|---|---|
Shallow Target Discovery (-quit / head) |
1.0× (Baseline) | ~8.5× | Up to 430× | bfs — BFS visits top-level entries before descending into massive directories. |
| Full Tree Traversal (Warm Cache) | 1.0× | 2.75× | 2.95× | bfs / fd — Both saturate hardware threads; bfs leads slightly via dircache. |
| Regex Pattern Matching (Warm Cache) | 1.0× | 10× – 23× | 3.5× – 6× | fd — Rust's SIMD-accelerated regex engine and auto-pruned `.git` tree. |
| Cold Cache Traversal (Disk I/O Bound) | 1.0× | 4.5× – 7.2× | 5.1× – 8.0× | Tie (bfs & fd) — Multi-threading saturates NVMe queue depths over single-threaded find. |
Syntax & Feature Comparison
Side-by-Side| Feature / Task | Traditional find |
bfs Syntax |
fd Syntax |
|---|---|---|---|
| Find by File Extension | find . -name "*.js" |
bfs -name "*.js" |
fd -e js |
| Case-Insensitive Search | find . -iname "*readme*" |
bfs -iname "*readme*" |
fd readme (Smart-case default) |
Ignore .git & Build Folders |
find . -name .git -prune -o -print |
bfs -exclude -name .git |
fd (Automatic default) |
| Skip Hidden Files | find . -name ".*" -prune -o -print |
bfs -nohidden |
fd (Automatic default) |
| Time-Based Filter | find . -mtime -7 |
bfs -mtime -7 |
fd --changed-within 7d |
| Size Range Filter | find . -size +100M -size -1G |
bfs -size +100M -size -1G |
fd -S +100M -S -1G |
| Parallel Batch Execution | Requires xargs -P |
bfs -j8 -exec cmd {} \; |
fd -x cmd {} or fd -X cmd |
| Prevent Symlink Loops | Complex manual check | bfs -L -unique |
fd -L |
| Rich Path Placeholders | {} only |
{} only |
{}, {/} (name), {//} (dir), {.} (no ext) |
Pros & Cons Matrix
Trade-Off AnalysisPROS
- Ultra-concise, intuitive syntax (
fd search_term). - Smart defaults: ignores
.gitignore,.ignore, hidden files, and binary files automatically. - Smart-case sensitivity (lowercase = insensitive; uppercase = sensitive).
- Rich replacement tokens for execution (
{/},{//,{.},{/.}). - Full native cross-platform support (Linux, macOS, Windows Scoop/Winget).
- Massive ecosystem adoption (default in
fzf, Telescope, Projectile).
CONS
- Incompatible with standard POSIX
findsyntax and shell scripts. - Default filtering can accidentally hide files in administrative/system contexts unless
-u/-His passed. - Non-deterministic output stream order across parallel worker runs.
PROS
- 100% drop-in replacement for POSIX, GNU, and BSD
find(alias find=bfs). - Breadth-First order finds shallow targets up to 430× faster on early exits.
- Advanced extensions:
-exclude,-nohidden,-unique(breaks symlink cycles). - Sophisticated C architecture:
ioqMPMC queue +dircacheopenat()LRU. - Ultra-permissive 0BSD license (public domain equivalent).
- Packaged in virtually all Linux/BSD repositories and Homebrew.
CONS
- Requires traditional verbose POSIX predicate expressions (
-name,-type). - Does not automatically parse
.gitignorefiles. - No native Windows binary support (strictly UNIX/POSIX-centric).
Which One Should You Use?
Decision Guidefd if you want:
Everyday interactive terminal navigation, searching inside Git repositories and codebases without seeing node_modules or target/ junk, interactive fuzzy-finding via fzf, or working on native Windows workstations.
bfs if you want:
A transparent 100% speedup for all existing shell scripts and sysadmin tasks via alias find=bfs, searching whole root filesystems (/), finding top-level files instantly with early exits, or maintaining strict POSIX/GNU compatibility.