GitHub 新仓库 fsearch 上线不到一天破 664 星:老需求为何突然翻红

发布时间:2026/10/10 2:55:08

GitHub 新仓库 fsearch 上线不到一天破 664 星:老需求为何突然翻红 GitHub 新仓库 fsearch 上线不到一天破 664 星老需求为何突然翻红【免费下载链接】fsearchWhole-disk file search for macOS: fuzzy names, typo tolerance, indexed content grep. ~1 ms over 8M files.项目地址: https://gitcode.com/gh_mirrors/fsea/fsearch「在我的电脑上找一个文件」这个需求二十年前就存在Windows 有 EverythingLinux 有 locate/fdfind而 macOS 用户至今只能在 Spotlight 的「内容优先」逻辑和find的龟速之间二选一。2026 年 10 月 8 日一个 Rust 写的 macOS 全盘搜索工具 fsearch 上线不到一天收获 664 星——它做的事没有任何发明但把「1 毫秒全盘按名搜索 容错拼写 索引内 grep」这三件事用原生系统调用做到了同类工具里罕见的完成度。本文基于仓库源码与社区情报拆解它的技术底牌以及这个老需求为什么在此刻翻红。一、24 小时快照一个单提交的仓库先看事实层面。本地仓库的 git 历史非常干净整个仓库只有一个提交时间戳 2026-10-08 13:59美东时间提交信息是「README: cut it down」没有 tagCargo.toml 里版本号还是 0.1.0MIT 协议。也就是说截至 10 月 9 日的舆情快照这个仓库处于「上线 24 小时窗口」内664 星全部是冷启动流量。按快照倒推若从发布到统计约为 12 小时平均星速约 55 星/小时。这个量级意味着什么对一个 0.1.0、无发布历史、无作者影响力的新工具仓库首日前 12 小时维持 50 星/小时以上的进星速率基本落在「当日 GitHub 最热项目」的区间——多数新 utility 仓库首日只能拿到两位数星数而即便是成熟的搜索类开源项目其星数也是数年累积的结果。一个值得注意的细节全网搜「fsearch」中文社区CSDN 等的大量存量内容指向的是另一个项目——基于 C 语言 GTK3 的 Linux 版 FSearch主打「Linux 上的 Everything」。而本次出圈的这条舆情头条号开源工具盘点中「fsearch 做全盘文件搜索支持模糊匹配和拼错容忍比系统自带快」描述的特征——模糊匹配、拼错容忍、比系统自带快——与 README.md 的 Rust/macOS 版完全对应与 C 版无关。同名不同物这一点后文会解释它如何助推了热度。项目的自我定位写得很直接README.mdWhole-disk file search for macOS: fuzzy names, typo tolerance, indexed content grep. ~1 ms over 8M files.测试环境是 M4 Max、770 万个文件和文件夹。官方口径的基线数据操作数值全盘按名找一个文件p50 1.3 ms文件内容搜索p50 9 ms新建/改名/删除的文件出现~0.1 s首次全盘建索引~20 s一次性守护进程内存30–135 MB二、老需求为何此刻翻红需求侧的三个猜测「找文件」不是新需求但 fsearch 的首日爆发不是偶然。结合仓库定位与社区舆情需求侧至少有三条可验证的推力。第一条macOS 的「Everything 空位」从未被真正填上。Spotlight 是内容检索优先的按名做模糊、容错匹配的搜索从来不是它的长项locate数据库陈旧find全盘一次要分钟级。Windows 用户把 Everything 当作装机标配已经十几年macOS 上没有对位产品——fsearch 的 README 通篇在跟「系统自带」和「全盘」两个词绑定社区盘点帖里「比系统自带快」也是第一卖点。这是典型的「金标准参照物已存在、本平台长期缺位」的需求结构供给一旦出现就会瞬间释放。第二条Apple Silicon 时代的文件规模把旧方案打穿了。一台开发机的 M 系 Mac 上 770 万个条目是常态demo/vs_fff_chromium.json 显示基准测试时守护进程索引了 8,283,289 个条目。在这个规模下「每次搜索都扫盘」的方案在交互延迟上不可用必须走「预建索引 事件增量」路线。换句话说需求一直在那但把「预建索引」做到 1 ms 交互延迟在旧硬件和旧文件系统工具链下并不划算macOS 原生的getattrlistbulk FSEvents 组合提供了足够低的建索引成本路线才第一次成立。第三条同名红利与「agent 基建」叙事的叠加。如前所述「fsearch」这个名字在中文技术社区已有数年、上千篇量级的内容沉淀新仓库天然享受搜索流量。另一个更深层的推力来自工具链形态fsearch 以 Unix socket 上的 JSON lines 协议暴露服务src/server.rs同时提供fsearch stdio直通模式与可链接的 Rust cratesrc/lib.rs。当前各类 AI 编码 agent 的普遍痛点之一正是「在 800 万文件的机器上快速定位文件」一个「50 ms 就绪、1 ms 查询」的本地检索原语天然适合作为 agent 的工具后端——README 里{op: grep, pattern: apply_dir}这类示例请求格式就是为程序调用者设计的。三、1 ms 是怎么来的索引结构是全部答案的一半fsearch 的速度不靠某个魔法而是一条完整的工程链。拆开看 src/walk.rs、src/index.rs、src/query.rs 三个文件能看清每一环。建索引一次系统调用吃掉一个目录。首次全盘扫描不逐文件 stat而是用 macOS/BSD 的getattrlistbulk(2)一次系统调用返回几百个条目名字、类型、大小、mtime、flags 全部附带。src/walk.rs 头部注释写得很明白One syscall returns hundreds of entries with name, type, size, mtime and flags already attached, so there is no per-file stat.目录树在 rayon 线程池上分治展开子目录用父目录 fd 的openat()打开路径永不重建。注释里还有实测数据这台 Mac 上open()close()每个目录约 19us有两个 Endpoint Security 客户端给每次 open 征税getattrlistbulk约 14us超过 8 线程后内核侧不再扩展——所以 src/engine.rs 里SCAN_THREADS定死为 8。全盘 770 万条目~20 秒建完。布局技巧子树就是一个连续区间。src/index.rs 的头部注释道出了整个索引的精髓Layout trick: entries are emitted one directoryblockat a time, blocks in depth-first order. So every directorys children are contiguous (and sorted, for path lookup), and every directorys whole subtree is the single rangedir_start..dir_end. Scoping a search to a folder is a range bound, not a filter.也就是说in:~/Developer这种目录范围过滤不是逐条比对路径而是查一次表得到[dir_start, dir_end)区间扫描直接收窄到区间内。src/query.rs 的scope_range()正是干这件事的路径 lookup 到目录取两个边界完事。名字驻留interning把 750 万次评分压到 200 万次。750 万条目里只有约 200 万个不同名字大量Package.swift、Cargo.toml、index.js重复出现。索引把每个名字存一份并附带字符掩码查询先对「唯一名字」评分再对条目打分。这直接对应 src/index.rs 里的FSIDX007魔数文件一个 mmap 的扁平 blob16 个 section零反序列化——Index::load就是Mmap::map进程重启后索引「加载」成本接近于零。连哈希器都是自写的 FxHash注释直言「interning 7.5M names wants a hasher cheaper than SipHash」。掩码预筛一条 AND 指令淘汰 99% 的候选。每个名字预先算好 64 位掩码低 41 位是字符类a–z、A–Z、0–9、.、-/_、空格、非标 ASCII 等高 13 位是「每个单词首字母」的哈希位。查询 token 能否匹配某个名字在 src/query.rs 的Token::fits()里是一次无分支的位运算fn fits(self, m: u64) - bool { let miss self.mask !m; (miss 0) | ((((miss !self.loose) | (miss miss.wrapping_sub(1))) 0) (m self.start ! 0)) }注释解释了无分支的用意——「branchless, so the scan over every name stays vectorized」。整个名字表并行扫一遍每个 chunk 写自己的位集切片大部分名字在这一步就被一个 AND 拒掉根本不会进模糊匹配。四、模糊与容错98% 的 top-1 命中率不是玄学按名匹配用的是 fzf-v1 风格的评分src/query.rsfuzzy_score_capped的注释直接点名最左结束匹配、右缩界、边界/驼峰/连续加成再加「整名 100 分 / 去扩展名 80 分 / 前缀 30 分」的落点奖励最后减去名字长度惩罚。匹配加速靠memchr的 SIMD 搜索——「most names fail on the first or second byte」。容错拼写是卖点实现上做了严格的成本控制。规则5 个字母以上的模糊 token 允许一个编辑距离TYPO_MIN_LEN: usize 5但只匹配「名字或空格分词的词首」且首字母必须正确——因为「所有名字里每个位置都试一遍错字」要付出约 10 倍代价src/query.rstypo_score的注释。为此索引掩码的高位存了每个词首字母的位查询先用m self.start ! 0把绝大多数名字拒掉剩下的才进one_edit_prefix()做一次单编辑前缀判定替换/删除/插入/交换数字不参与容错——注释里的理由是「hat_18不是hat_98的笔误是另一个文件」。命中的错字匹配再扣 60 分TYPO_COST保证干净的同质匹配排在前面。基准测试把这个能力量化了。demo/vs_fff.py 的方法论值得细看从 Chromium 源码树508,652 个文件里确定性随机抽 300 个「唯一名」文件作为目标生成 1500 条查询含 swap/drop/extra/subst 四类人工笔误两个引擎「轮流先手」跑消除冷热缓存偏差内容搜索用 67 个从随机源文件里抽的真实标识符加 7 个常见模式。结果demo/vs_fff_chromium.json指标Chromium509k 文件fsearchfff按名查找 p501.05 ms13.8 ms内容 grep p50 / p905.6 ms / 40.7 ms53.4 ms / 583.6 ms精确查询 top-1 命中100%99.7%笔误查询 top-1 命中98%87.8%启动到就绪50 ms2.5 s内容缓存再 12.8 s内存占用50 MB全盘索引358 MB单个文件夹另一组对照是 Linux 内核源码树95,939 个文件demo/vs_fff_linux.json按名查找 1.15 ms 对 1.04 ms基本打平笔误 top-1 97.75% 对 92.83%grep 4.28 ms 对 22.79 ms。README 没有回避这一点明确写了「name search is a tie and fsearch wins the rest」。小文件夹上名字查找打平是诚实的——名字索引的扫描成本对 9.6 万个条目来说本就不是瓶颈。五、保持「不陈旧」事件层与内容索引搜索工具最难的不是快是「快且不撒谎」。fsearch 的增量层在 src/live.rs不可变基线索引 一个 dead 位集标记已删除条目 一个 overlay新增条目。所有 FSEvents 目录事件走同一条路——「列那个目录跟现有内容做 diff」diff 幂等所以历史重放、重复事件、与压缩操作竞争全都无害。事件流在 src/fsevents.rs 用 0.1 秒延迟订阅/按事件 id 可重放守护进程重启只重放上次保存之后的事件。新文件从产生到可搜约 0.1 秒。兜底逻辑同样严谨FSEvents 丢事件内核丢弃/用户空间丢弃/历史不可用时src/engine.rs 的relist_changed()不是重扫全盘而是只重列「上次同步点减 120 秒余量」以来变动过的目录注释称「Seconds, instead of recrawling the whole disk」。overlay 积压超过 5 万条、或超过 12 小时没存盘才触发一次全量压缩落盘约 1 秒 CPU、280 MB 写入。内容搜索是一层独立的三元组trigram索引src/content.rs不可变、mmap 的分段文件每段一张文档表加每个三元组到文档 id 的倒排列表delta varint超过 1/8 文档命中时自动切位集。查询展开成三元组 AND/OR 选出候选文件然后候选内容从磁盘现读现匹配——所以结果永远不会展示陈旧内容最多是「最后两秒刚写的文件还没进候选」。索引同步走的是与名字索引相同的 diff 思路node_modules、.git、target、DerivedData等 40 多个目录名直接跳过单文件上限 1 MB。更新节奏也做了防抖目录在「最后变更 2 秒后」处理一直不消停的目录 5 分钟封顶一次——「你保存的文件 ~2 秒入库每秒被应用重写的文件state、日志每分钟变一次也只触发一次重建索引」。一个诚实的代价写在 README 里fff 在内容搜索上多覆盖约 9% 的文件因为 fsearch 跳过了build/、vendor/等目录。基准数据印证Chromium 树上 67 个模式双方共同命中 323,667 个文件fff 命中 353,276 个fsearch 323,688 个。六、产品化细节看出「真实用户写的工具」星数之外fsearch 更值得抄作业的是一批「被坑过才写得出」的细节一索引多进程共享owner/follower 模型。守护进程用flock拿索引写入权任何其他链接此 crate 的 app 启动时发现锁被占就转 follower——读磁盘上已存的索引、内存里保持鲜活owner 挂掉时自动接管src/engine.rstry_upgrade。README 的表述是「An app and the CLI share one index」这正是把搜索能力卖给第三方 app 的形态。Full Disk Access 的摩擦处理。macOS 的隐私授权弹窗会阻塞调用。fsearch 的对策是没有 FDA 时直接跳过 Desktop/Documents/Downloads/云盘/照片库等需授权目录src/engine.rsgated()「skips the protected folders instead of popping a prompt」绝不卡住用户fsearch install --login装 LaunchAgent 时才会引导单独授权。iCloud 占位文件免疫。主进程与各工作线程都调用setiopolicy_np关闭 dataless 文件物化src/engine.rsno_materialize注释说明动机「Never let a search download iCloud placeholders」——否则搜一下全盘可能触发几百 GB 的云端下载。自写全局分配器。src/main.rs 为守护进程实现了自定义GlobalAlloc大于 1 MiB 的分配直接mmap/munmap。注释里是真实事故「macOSs malloc keeps freed large blocks mapped and dirty, which left the daemon at ~1 GB footprint after a build while only ~2 MB was live」。配合malloc_zone_pressure_relief把峰值内存压进 README 宣称的 30–135 MB。QoS 分档。搜索线程池被显式抬到QOS_CLASS_USER_INTERACTIVE否则会被 app 后台 executor 拖到 efficiency 核上内容索引线程降到QOS_CLASS_UTILITY——交互路径和后台路径各走各的优先级。可复现的基准。fsearch bench子命令src/main.rs对已存索引跑 20 次取 first/median/min对比脚本 demo/vs_fff.py 全仓库公开先杀守护进程冷启动计时footprint命令测内存引擎轮流先手。README 附的视频 demo/fsearch-vs-fff.mp4 与两份 JSON 原始数据一起躺在仓库里任何人都能复算。七、下一轮要盯的验证点热度数据之外的风险点同样可以从仓库里读出动量衰减窗口。首日是「macOS 没有 Everything」的情绪盘。接下来两周星数曲线是否维持两位数/日取决于 FDA 授权这一最大 onboarding 摩擦能否被install --login流程消化——它要求用户在系统设置里给~/.local/bin/fsearch单独授权且每次重编译后重新授权README 原话「again after each rebuild」。macOS-only 是硬边界。核心路线getattrlistbulk、FSEvents、TCC、LaunchAgent、iCloud policy全是 Apple 平台 APILinux 上的「96k 文件」只是基准测试用的内核源码目录不是跨平台支持。664 星里有多少是「Linux 用户也想用」的期待值得观察 issue 区的构成。单提交、无 tag、0.1.0。工程质量很高但工程成熟度是另一回事FSIDX007、FSCSEG03这类魔数说明索引格式在迭代后续版本可能伴随磁盘索引重建。内容索引的覆盖取舍。跳过 40 多个目录名 1 MB 单文件上限换来的是内存与延迟对「我的文件都在 Documents」的普通用户无感对「我要 grep 到 vendor 里」的开发者则是 9% 的可观测缺口。「找文件」这个需求翻红不是因为需求变新了而是因为一个持续十几年的平台空位macOS 的 Everything第一次被一条干净的路线批量系统调用建索引 事件流增量 mmap 扁平结构以 1 ms 的量级填上了。fsearch 的真正价值不在某个算法而在把「建索引成本、增量一致性、macOS 特有问题FDA/iCloud/内存占用」这一串脏活全部收在 10 来个 Rust 文件里。至于 664 星是起点还是峰值答案不在 README 里在未来两周的 issue 区和下一个 tag 里。【免费下载链接】fsearchWhole-disk file search for macOS: fuzzy names, typo tolerance, indexed content grep. ~1 ms over 8M files.项目地址: https://gitcode.com/gh_mirrors/fsea/fsearch创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/10 2:50:08

2026跨境电商新规落地后,这3类卖家正在悄悄被市场淘汰

平台规则从来不是突然转向,而是先释放信号,再逐步收紧。进入2026年,跨境电商行业最明显的变化不是流量变贵,而是合规成本开始成为经营门槛。过去靠信息差、铺货速度和低价冲量就能活下来的模式,正在被一条条新规拆解。…

2026/10/10 2:50:08

2026年跨境电商卖家别再盲目铺货了,这3个长尾词赛道正在悄悄爆单

铺货模式曾支撑起不少卖家的早期增长,但当平台流量分配更依赖精准匹配、海外消费者对交付与内容的要求同步提高后,单纯靠SKU数量换曝光的做法,边际收益已经明显收窄。与其在红海里反复测款,不如把注意力转向搜索意图更明确、竞争密…

2026/10/10 2:50:08

盟接之桥谈线束:精益生产+半自动化,不止是软件的组合拳

数字化不是万能药,没有精益的数字化是空中楼阁近年来,制造业数字化转型热潮席卷各行各业,线束企业也不例外。很多企业投入大量资金采购了ERP、WMS、MES等信息化系统,期望"上了系统就能解决所有管理问题"。然而现实往往令…

2026/10/10 5:40:15

64位token:结构化数据的内存压缩与零拷贝计算

1. 为什么64位token能扛住结构化数据的“内存雪崩”?看到标题里“内存占用降70%”这个数字,我第一反应不是惊喜,而是皱眉——这背后一定藏着某个被长期忽视的底层设计债。过去三年里,我参与过五个不同规模的数据处理系统重构&…

2026/10/10 5:40:15

告别“无标题”:起标题的流程、误区排查与信息块组合法

最近在整理素材库的时候,翻到几个月前存的一篇草稿,文件名是一长串乱码,正文写了三千多字,可文章开头的位置,标题栏空空如也。我盯着那个空白框想了半天,愣是想不起当时准备写一篇关于什么的东西。这就是典…

2026/10/10 5:40:15

OpenClaw 卸载完全指南:Windows 端、WSL2 与残留清理

把 OpenClaw 叫成“龙虾”,多半是已经把它当成了日常工具里的一员。当初照着教程一层层搭起来的时候,Node.js、WSL2、Ollama,每装好一个组件都挺有成就感;可真到了要卸载的时候,才发现它不是一个能“右键删除”的普通软…

2026/10/10 5:40:15

Python项目CI/CD实战:从依赖管理到自动化部署的完整指南

1. 为什么Python项目也离不开CI/CD先说个我踩过的大坑。几年前维护一个内部Python工具库,二十来号人往里提交代码,每次合并都是手动在本地跑一遍测试再推上去,结果几乎每个月都会出现"我这边明明能跑啊"的灵异事件。后来实在受不了…

2026/10/8 10:03:18

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/9 20:15:56

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/8 6:05:44

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 0:04:53

从逻辑门到计算机:数字电路核心原理与全加器搭建实战

如果你拆过一台旧电脑的主板,盯着那些黑乎乎的小芯片看上一会儿,可能会冒出同一个疑问:这堆引脚密集的元件,到底是怎么“变”出那么复杂的应用的?答案并不在某个神秘的部件里,而是在所有芯片内部都在反复使…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑