在Erlang/OTP中gen_server调用的开销是多少?

ijt*_*ijt 3 erlang erlang-otp

关于Erlang可伸缩性的这篇文章说,每次调用,转换或发送给gen_server的消息都会产生开销.它有多少开销,它有什么用?

zxq*_*xq9 6

引用的成本是对外部模块的(相对盲目)函数调用的成本.发生这种情况是因为gen_*抽象中的所有内容都是对外部定义函数(您在回调模块中编写的函数)的回调,而不是编译器可以在单个模块中优化的函数调用.这个成本的一部分是调用的解析(找到正确的代码来执行 - 同样的原因,在Python或Java中的每个"dot"in.a.long.function.or.method.call提高了解决的成本)而另一部分成本是实际的呼叫本身.

这不是您可以计算为简单数量的东西,然后乘以获得有关整个系统的运营成本的有意义的答案.

在像Erlang这样的大规模并发系统中有太多的变量,约束点和意想不到的廉价元素,其中并发的最难部分被抽象出来(调度相关问题)并且最昂贵的并行处理元素变得非常便宜(上下文切换) ,处理spawn/kill和process:memory ratio).

只有这样,才能真正了解一个大规模并行系统,由于其本身的性质将表现出什么突发行为,是写一个和在实际操作中进行测量.你可以在纯二郎再次使用gen_*抽象写完全相同的程序一次,然后作为OTP应用和测量性能这样的区别-但基准数字只会意味着什么,以特定的程序,可能只意味着什么下特定的负载配置文件.

所有这些都考虑到了......当我们开始在Erlang世界中分裂头发时真正重要的数字是调度程序考虑的减少预算成本.Erlang Solutions的Lukas Larsson不久前发布了关于调度程序的视频,详细说明了这些成本对系统的影响,它们是什么,以及如何在某些情况下调整值(了解Erlang调度程序).除了与Erlang/OTP无关的外部资源(iops延迟,网络问题,NIF疯狂等)之外,压倒性因素是调度程序的行为,而不是"函数调用的代价".

但是,在所有情况下,真正了解的唯一方法是编写一个原型,表示您在实际系统中所期望的基本行为并对其进行测试.