Unix "find" Expressions Compiled to Bytecode
Key topics
The Unix "find" command's performance is being reevaluated after a blog post revealed that compiling its expressions to bytecode could be a potential optimization. Commenters chimed in, pointing out that the real bottleneck lies in file system calls, with tasty_freeze estimating that evaluating conditional expressions takes up only a tiny fraction of the overall time, while CerryuDu highlighted the impact of loading directory entries and inodes on a cold cache. Interestingly, nasretdinov and loeg discussed how certain file systems and system calls, like readdirplus and d_type, can mitigate the need for additional stat() calls, with nasretdinov noting that NFS seems to handle subsequent stat() calls efficiently. The discussion also touched on why most "find" implementations use tree-walk interpreters, with drob518 arguing that it's simply because it's easier to implement, not due to performance reasons.
Snapshot generated from the HN discussion
Discussion Activity
Active discussionFirst comment
3h
Peak period
13
0-12h
Avg / period
6
Based on 18 loaded comments
Key moments
- 01Story posted
Dec 26, 2025 at 7:35 AM EST
7 days ago
Step 01 - 02First comment
Dec 26, 2025 at 10:39 AM EST
3h after posting
Step 02 - 03Peak activity
13 comments in 0-12h
Hottest window of the conversation
Step 03 - 04Latest activity
Dec 30, 2025 at 11:53 PM EST
2d ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
NFS has readdirplus, but I don't think it ever made its way into Linux/POSIX. (Some filesystems could efficiently return dirents + stat information.)
Well, it definitely does _something_, because on NFS the subsequent stat() calls after reading the directory names do indeed complete instantly :), at least in my testing.
> I was later surprised all the real world find implementations I examined use tree-walk interpreters instead.
I’m not sure why this would be surprising. The find utility is totally dominated by disk IOPS. The interpretation performance of find conditions is totally swamped by reading stuff from disk. So, keep it simple and just use a tree-walk interpreter.
And then I pointed to this article on databases: https://notes.eatonphil.com/2023-09-21-how-do-databases-exec...
Even MySQL, Duck DB, and Cockroach DB apparently use tree-walking to evaluate expressions, not bytecode!
Probably for the same reason - many parts are dominated by I/O, so the work on optimization goes elsewhere
And MySQL is a super-mature codebase
Sounds like many DBs do some level of compilation for complex queries. I suspect this is because SQL has primitives that actually compute things (e.g. aggregations, sorts, etc.). But find does basically none of that. Find is completely IO-bound.
SQLite talks about the reasons for each variation here: https://sqlite.org/whybytecode.html
For instance, I normally compile big software projects in RAM disks (Linux tmpfs).
Such big software projects may have very great numbers of files and subdirectories and their building scripts may use "find".
In such a case there are no SSD or HDD I/O operations, everything is done in the main memory, so the intrinsic performance of "find" may matter.
For archiving, I also wrote a parallel walker and file hasher that only does one pass of data and stores results to a sqlite database. It's basically poor-man's IDS and bitrot detection.
Did you ever compare what you wrote to that?