
Linus Torvalds是个非常厉害的程序员炒股配资开户网站,因为他有两个名扬天下的作品:Linux和Git。
如果单论技术能力,有一个人,也许比Linus更强。
我在看他主页项目列表的时候,感觉头都炸了。
他开发了著名的模拟器QEMU和音视频处理库FFmpeg,仅仅是这两项就超越绝大部分程序员了,他还写过C编译器,OpenGL实现,LTE软基站,JS引擎,让Linux在浏览器中跑起来,甚至还创造了计算圆周率的世界纪录......
也就是说,这位老兄在操作系统、模拟器、多媒体、计算机图形学、编译器、编程语言、通信、甚至数学等领域跳来跳去,一年开发一个我一辈子都写不出的软件!
他写的程序还总是比别的程序小几个数量级,快几个数量级!
这也太变态了吧?!
不得不承认,这个世界上真的有天才的存在。
他就是法国程序员Fabrice Bellard。

Bellard还有个重要的特点,写了一个厉害软件,开创了一个领域,就把工作交给社区维护,自己拍拍屁股走人,挑战另外一个难题。
这不,最近Fabrice Bellard又出手了,这次他带来了一个叫做MicroQuickJS的开源项目。
这也是个JavaScript引擎,不过面向的是嵌入式设备。
我去项目主页看了一下,好家伙,MicroQuickJS引擎运行时仅需10K的内存就可以编译和运行JavaScript程序,在这么小的空间下,运行速度还接近QuickJS (这也是Bellard写的另外一个轻量级的JS引擎)。
才10K! 想想Node.js,想想Chrome V8,再想想Electron,这种极致的优化能力实在是可怕。
怪不得Redis之父antirez说:如果这东西2010年就出现了,Redis的脚本语言就不会是Lua,而是JavaScript!

为什么 MicroQuickJS 可以这么小?
因为它不是在“移植 JavaScript”,而是在“重新定义 JavaScript 在嵌入式设备上该是什么样子”。
1. 只支持 ES5 的一个“精简版”
MicroQuickJS 支持的不是我们熟悉的那个“什么都能写”的 JavaScript,而是一个被刻意约束过的版本。
举几个例子你就能理解它的取舍逻辑:
- 只支持 strict mode,不再兼容历史包袱,行为更简单、更可预测,也更容易优化。
- 数组不允许有“空洞”也就是说,不存在 arr[100] = 1,前面 99 个元素却不存在的情况。这样数组就可以用更紧凑的方式存储,而不是像散弹枪一样到处打洞。
- 不支持直接 eval,eval 会让代码在运行时突然“变身”,对内存管理和优化来说是噩梦。直接砍掉,整个引擎都清爽了。
- 日期只支持 Date.now(),不搞复杂的时区、格式化、历史包袱,只提供“当前时间戳”这个嵌入式最常用的功能。
- 字符串大小写转换只支持 ASCII, 不支持完整 Unicode 的大小写映射,换来的是代码量和内存占用的大幅下降。
这些限制看起来有点“怪”,但你会发现它们都有一个共同目标: 确定、简单、省内存。
2. 垃圾回收:不聪明,但非常狠
在内存只有几十 KB 的环境里,内存碎片比“内存不够”更致命。
MicroQuickJS 的垃圾回收策略非常直接:追踪式+压缩式GC。
第一层:追踪式 GC
它从一组“根对象”开始,把所有还能被访问到的对象标记出来,剩下的一次性全清。
不需要在每个对象上维护引用计数,不用担心循环引用。
每个对象可以做得非常小,只需要几个 bit 的标记信息
第二层:压缩 GC
更狠的是:活下来的对象也不会原地不动。在回收过程中,它会把所有存活对象重新排列、挤到一块连续的内存区域里。
内存不再被切成一地碎片,后续分配变得非常简单,对小内存设备极其友好
MicroQuickJS 完全不用系统的 malloc,而是自己实现了一套内存分配器,这在嵌入式世界里非常重要,因为你永远不知道系统自带的分配器会偷偷浪费多少内存。
3. 用“变态”的方式表示 JS 的值和对象
这里是 Bellard 真正“炫技”的地方。
在 MicroQuickJS 里,一个值(数字、字符串、对象、函数等)统统只有一个 CPU 字长。
在 32 位系统上,就是 32 位,这意味着:所有值都能直接放进寄存器,传参、赋值、判断都极其简单,内存布局非常规整。
对象被压缩到了极限,一个 JavaScript 对象,最少只占 3 个 CPU 字,在 32 位系统上就是 12 字节,这已经是能做到的极限了,只够存对象的基本类型信息和指向属性表的指针。
属性本身也不便宜,每个属性至少 3 个 CPU 字,所以“随便给对象乱加属性”在嵌入式里是很奢侈的事。这也解释了为什么语言层面要对动态性做那么多限制。
字符串也不走寻常路,内部存储用的是 UTF-8(更省空间),对外仍然表现为 JavaScript 熟悉的 UTF-16 语义,也就是说,存的时候省,语义上不破坏 JS 的规则。
4. 标准库直接“焊死”在 ROM 里
在很多 JS 引擎中,启动时要创建 Object、Array、Math 等一大堆对象,这些对象会常驻内存,占用 RAM。
MicroQuickJS 直接换了个思路: 编译时就把这些标准库对象生成好,以只读数据的形式,固化进程序镜像,放在 ROM 里。
运行时不需要再创建,只要引用即可,启动极快,RAM 占用极低。
总之,在嵌入式世界里,JavaScript 不再是“越全越好”,而是“刚刚好,能用就行”。
杰夫·阿特伍德(Jeff Atwood)说过,“任何可以用 JavaScript 编写的应用程序,最终都会用 JavaScript 编写”。

这句话现在也适用于嵌入式系统了!
也许在不就以后,我们就能在传感器、智能家居设备和可穿戴设备上看到JavaScript。
回到作者Bellard,他为人非常低调,不抛头露面,不写文章,不写书。
在互联网上几乎找不到对他直接的,深度采访,只能找到他的一些只言片语,例如:“我经常会厌倦一直做同样的事情,所以我会时不时地改变一下方向。”
由于他在如此多的领域,做出了常人根本无法企及的,不可思议的成就,有人甚至怀疑他就不是一个特定的人,而是一群人以这个id来发表软件。
我想Bellard之所以看起来像“一群人”,并不是因为他不真实,而是因为我们早已习惯了工业化软件生产,却突然遇到了一个仍然生活在“个人英雄时代”的程序员。
在今天这个时代,大多数重要软件都需要庞大的团队、路线图、测试、运营;而 Bellard 的作品,总是像从真空中掉下来一样:没有预热、没有宏大宣言,代码一放出来,世界就不得不承认:规则被改写了。
这样的人实在是太罕见,实在是太神奇了!
天元证券提示:文章来自网络,不代表本站观点。