超光速

Back

JavaScript 运行时 LLRT

简介

LLRT 低延迟运行时是一个基于 Rust 构建的轻量的 JavaScript 运行时,利用 QuickJS 作为 JavaScript 引擎。它旨在提供快速启动和高效内存使用,适用于 Serverless 应用。

项目自述

LLRT (Low Latency Runtime) is a lightweight JavaScript runtime designed to address the growing demand for fast and efficient Serverless applications. LLRT offers up to over 10x faster startup and up to 2x overall lower cost compared to other JavaScript runtimes running on AWS Lambda

Warning
LLRT is an experimental package. It is subject to change and intended only for evaluation purposes.

项目 https://github.com/awslabs/llrt
简介 基于 Rust 构建,利用 QuickJS 作为 JavaScript 引擎的一个运行时。可快速启动,并且内存占用较小。

测试版本 LLRT (linux x64) 0.1.15-beta
二进制文件大小 6.87MB 无动态链接

特性

LLRT 基于 QuickJS 作为 JavaScript 引擎,没有 JIT 。启动速度快,内存占用较小,长期性能不足。并且 LLRT 并不提供完整的 Node.js API。

评论

新的JavaScript运行时入局:LLRT 2024-02-23
作者:纪轻昀
链接:https://juejin.cn/post/7338314540303482919
来源:稀土掘金

关于内存占用,AWS的博文《AWS 的新 Lambda 运行时 LLRT 怎么样》中提到:

LLRT 在大多数配置中得分都非常好, 通常是第三快的运行时,仅次于 C++ 和 Rust。在这种情况下,它甚至比 Golang 还要快。
当然,你要记住,C++和Rust 是非常成熟的生态系统,相对而言也是如此,而且这仍然是一个实验性的测试产品。
在基准测试中,我们还可以看到内存使用情况的差异,如果我们将 LLRT 与 Node 20 进行比较,我们会发现,我们的内存使用量为 24 MB,而 Node 20 为63 MB, 因此大约是同一 Lambda 函数所需内存的三分之一。

然而,对于LLRT的评价存在一些不同的声音,并非所有用户都买账。

在Reddit的一个帖子中,一位回复者解释道:

速度提升主要来自于一种限制:LLRT 要求将代码和依赖项打包到一个单独的 .js 文件中,从而消除了 Node 模块解析阶段发生的所有文件系统查找。

此外,他们预先打包、预编译(为字节码)和预加载AWS SDK的部分内容,然后将其与需要在应用程序启动时加载 AWS SDK库的通用运行时(如 Node 或 Bun)进行比较。我敢打赌,这就是 99% 的性能收益来源。

Hacker News的一个帖子中,一位回复者评论道:

这似乎非常适合用 Lambda 作为粘合剂的场景,比如用于路由请求或授权策略决策。但对于一个做大量思考的应用程序,记住v8 jitless 比 QuickJS 快大约3倍,有 JIT 时比 QuickJS 快大约30倍。我很想知道在各种工作负载中比较这两种方法的收支平衡点,以及与 Bun 的比较数据,后者比 Node 启动更快,但具有可比较的顶级 JIT 性能。

一位程序员兼软件架构师 Zemnytskyi Dmytro 在推特上写道:

这将进一步复杂化 Lambda 开发。不兼容的依赖和工具。更多的供应商锁定。我对此持怀疑态度。我宁愿用 Rust 完整地编写 Lambda。

关于这些缺点,LLRT并不否认,在其GitHub说明文档里也写道:

与JIT(Just-In-Time)技术相比,LLRT在处理大数据、蒙特卡洛模拟或执行数十万甚至数百万次迭代的任务时性能明显不足。 LLRT的设计目的是作为现有组件的补充,而不是全面替代一切。 值得注意的是,由于其支持的API基于Node.js规范,切换回替代解决方案只需要进行最少量的代码调整。

实践

LLRT 不提供完整的 Node API 支持,需要注意。并且根据自述文件提供的方法,最好使用 Rollup 打包。

使用 LLRT Rollup 打包

npm install --global rollup
pnpm init
pnpm i @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-terser
rollup --config rollup.config.mjs
bash

https://cn.rollupjs.org/
rollup.config.mjs

main.js

性能测试

一个不处理溢出的 fib , 传入 500 和 5000 。这段 js 代码修改了几次,相关日志没有记录是哪个版本的。不保证 500 和 5000 代码一致。

下面没有给出 C,Rust,Go,Lua,LuaJIT 等测试结果。
从花费时间上看,计算量较大时,速度从快到到慢为 C Rust LuaJIT Go Lua5.1 Bun Deno Node LLRT。
计算量小时,LLRT 在 JS 运行时中最快。而 LuaJIT 并不稳定,有时比 Lua5.1 还慢一点。

简单片面的性能测试结果,仅供参考

fib.js

500 次结果

5000 次结果

总结

LLRT only support a fraction of the Node.js APIs. It is NOT a drop in replacement for Node.js, nor will it ever be. Below is a high level overview of partially supported APIs and modules. For more details consult the API documentation

LLRT 启动快,有一部分 Node API,无动态链接。可以放在 Docker Alpine Linux 中使用。

如果缺少什么 API ,也可以参考源码自己实现。

另外这个项目使用 Zig 链接,多平台静态编译也是值得参考的。

JavaScript 运行时 LLRT
https://www.ftls.xyz/posts/2024-08-01-llrt/
Author 恐咖兵糖
Published at
Copyright CC BY-NC-SA 4.0