看大家都在聊 bun 1.0 ,我也来凑个热闹
项目地址 https://github.com/codehz/bun_python
demo 代码:
import * as np from 'python:numpy';
import * as plt from 'python:matplotlib.pyplot';
const xpoints = np.array([1, 8]);
const ypoints = np.array([3, 10]);
plt.plot(xpoints, ypoints);
plt.show();
迁移自 deno_python ,主要用于测试和学习 bun 的 FFI 和 plugin 机制的使用
此外发现 bun 的 ffi 性能确实值得一提,思路和 deno ffi 一模一样,api 也大差不差,但性能却能打得过 deno ffi (当然 node napi 肯定也能秒),bun ffi 的这个思路,我在很久之前也在tjs(该项目已废弃)也尝试过,有趣的是,同样用的 zig ,同样用的 tcc 做 native bridge ,只不过我直接把 tcc 的 api 接驳到 js 里使用,而 bun 则是生成一个 c wrapper 代码来做 bridge ,用 tcc 直接 jit 出转换的代码,性能又有进一步提升,加上 JavaScriptCore 引擎自己对 ffi 的优化(特别是相比于 v8 )性能几乎提到了 luajit 的那种水平,deno 虽然 api 看着类似,但实现也完全不同,这大概是性能差距的来源
此外 bun 的 plugin 机制可以直接定义 import 导入语句的行为,由于它是直接和引擎集成,因此相比于 bundle/transpiler/preprocess 的方案,它可以支持 plugin 直接给导入的模块返回对象——而无需生成一系列 export 代码(总所周知,esm 的 named export 需要静态确定),在这个场景下,实现一句话 import * as torch from 'python:torch';
即可使用 pytorch
某种意义上在 bun 里实现 deno 的 url import 也是可能的,就看有没有人做()
(话虽如此,我也不建议在玩具场景外使用 bun_python 这个库来加载和使用 python ,首先你丧失了最重要的进程隔离,其次我这个库实现的也比较粗糙,很多边界问题都没考虑到)