通过系统调用与其他语言互操作对性能有何影响?

What are the performance implications of interopping with other languages via system calls?

假设我正在用 node.js(或者可能是另一种典型的后端脚本语言)编写程序。进一步假设我有一个 C 函数 f(或 python 函数,或者你有什么)做一些纯数据转换。

如果我想在我的节点程序中使用f,有两种方法:

  1. 通过 node-gyp 之类的东西绑定 f,使其可以从 JavaScript 土地调用。
  2. f 制作成位于文件系统上的二进制文件(或者,在像 python 这样的语言的情况下,单个 f.py 接口),然后调用它来自节点,就好像是任何其他系统命令一样(这样就可以将系统调用的输出作为字符串,将其转换为 node.js 数据,然后使用它)。

问题:选择 (2) 而不是 (1) 对性能有何影响?

这很重要,因为如果您使用像 C 这样的语言来使应用程序的某些方面 运行 显着加快,那么使用 (2) 如果它减慢了某个阈值,那么使用 (2) 似乎毫无意义。

1的成本是加载本机代码、传输参数(ffi)、调用本机代码和传回参数的成本。只加载一次。

2 的成本始终是启动进程的成本,运行启动进程,将结果从字符串转换回。

如果f的成本很高,你可能永远看不出1和2的区别。如果f的成本很低,那么2会花费更长的时间,因为进程启动开销将占主导地位。

但是,根据 f 的复杂性(它可能是一个非常大的 C 数据处理应用程序),创建像 1 这样的本机绑定几乎总是更快。避免进程启动开销很重要, 它还减少了 运行 您的应用程序所需的内存总量。

或者您可以选择:

  1. 让 C 代码通过本地网络套接字进行通信。计算完成后接受请求并回复答案。

这有利于在需要时扩展到多个节点。

为您的用例进行基准测试是唯一可以确定的方法,但方法 1 是 可能会更快。

为 python/perl/blah 调用二进制文件和启动解释器的启动成本可能会扼杀您使用其外部函数接口 (FFI) 可能获得的任何性能提升。启动成本是 Apache 拥有 mod_python、mod_perl 以及 FastCGI 存在的原因之一。

另一件需要考虑的事情是,您正在向混合中添加另一种语言,这可能会扼杀 团队的绩效 即现在每个人都需要了解两种语言和两种 FFI 方法等等,如果你的应用在Node中,就把它放在Node中,用node调用native方法。