Node.js 通过系统调用与其他语言交互的性能影响是什么?

Node.js 通过系统调用与其他语言交互的性能影响是什么?,node.js,interop,Node.js,Interop,假设我正在node.js(或者另一种典型的后端脚本语言)中编写一个程序。进一步假设我有一个C函数f(或者一个python函数,或者你有什么)来执行一些纯数据转换 如果我想在我的节点程序中使用f,有两种方法: 通过节点gyp之类的东西绑定f,使其可以从JavaScript领域调用 将f转换为文件系统上的二进制文件(或者,对于python这样的语言,是单个f.py接口),然后从节点调用它,就像调用任何其他系统命令一样(这样就可以将系统调用的输出作为字符串,将其转换为node.js数据,然后使用它)

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

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

  • 通过节点gyp之类的东西绑定
    f
    ,使其可以从JavaScript领域调用
  • f
    转换为文件系统上的二进制文件(或者,对于python这样的语言,是单个
    f.py
    接口),然后从节点调用它,就像调用任何其他系统命令一样(这样就可以将系统调用的输出作为字符串,将其转换为node.js数据,然后使用它)
  • 问题:选择(2)而不是(1)对绩效有什么影响


    这一点很重要,因为如果您使用像C这样的语言使应用程序的某些方面运行得更快,那么如果使用(2)将速度降低到某个阈值以上,那么使用(2)似乎毫无意义。

    1的成本是加载本机代码、传输参数(ffi)、调用本机代码、,把论点转回来。加载只进行一次

    2的成本始终是启动流程、运行流程、将结果从字符串转换回来的成本

    如果
    f
    的成本很高,您可能永远看不到1和2之间的差异。如果
    f
    的成本较低,那么2将花费较长的时间,因为进程启动开销将占主导地位

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

    或者,您可以选择:

  • 让C代码通过本地网络套接字进行对话。接受请求并在计算完成时以答案进行响应

  • 如果需要,可以扩展到多个节点。

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

    2的成本始终是启动流程、运行流程、将结果从字符串转换回来的成本

    如果
    f
    的成本很高,您可能永远看不到1和2之间的差异。如果
    f
    的成本较低,那么2将花费较长的时间,因为进程启动开销将占主导地位

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

    或者,您可以选择:

  • 让C代码通过本地网络套接字进行对话。接受请求并在计算完成时以答案进行响应

  • 如果需要的话,这有扩展到多个节点的好处。

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

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


    另一个要考虑的是,你在混合中添加另一种语言,这可能会影响团队的性能。现在,如果你的应用程序在节点中,那么每个人都需要知道两种语言和两种FFI方法。将其保存在Node中,并使用Node调用本机方法。

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

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


    另一个要考虑的是,你要在混合中添加另一种语言,这可能会影响团队的性能。现在每个人都需要知道两种语言和两种FFI方法。如果你的应用程序在节点中,将其保存在节点中,并使用节点调用本机方法。似乎您不会将

    f
    外包给另一种语言,除非运行
    f
    的成本很高(在这种情况下,启动时间没有那么重要,并且(2)变得相对不那么糟糕)在另一种语言中调用<代码> f>代码可能是因为您需要使用当前语言中不可用的语言的特性,如直接访问硬件或系统,这些系统没有被任何方式暴露给您,例如MeDebug、MMAP或另一个问题:用C语言或C++语言这样说是公平的,在启动时间基本为0的情况下,(2)的附加成本仅仅是从字符串转换结果的成本?在实践中,似乎您不会将
    f
    外包到另一种语言,除非运行
    f
    的成本很高(在这种情况下,启动时间没有那么重要,(2)变得相对不那么糟糕)在另一种语言中调用<代码> f>代码可能是因为您需要使用当前语言中不可用的语言的特性,如直接访问硬件或系统,这些系统没有被任何方式暴露给您,例如MeDebug、MMAP或另一个问题:用C语言或C++语言这样说是公平的,如果启动时间基本为0,则(2)的附加成本仅为转换结果f的成本