[Erlang 0058] Erlang Function调用效率

简介:

   Erlang方法调用有m:f(a),M:F(a),fun,f(),apply/3几种方法,调用效率如何呢?《Erlang/OTP in Action》一书中有一个总结我们看下:

 
 
  即模块内调用和模块间的方法调用速度差异不大;要关注一下元编程方式调用(apply调用)要慢的多,除此之外除非是在性能要求特别高的场景否则不必过于在意这点性能差异;这个在官方文档中有大致相同的结果:
 

Here is an intentionally rough guide to the relative costs of different kinds of calls. It is based on benchmark figures run on Solaris/Sparc:

  • Calls to local or external functions (foo(), m:foo()) are the fastest kind of calls.
  • Calling or applying a fun (Fun(), apply(Fun, [])) is about three times as expensive as calling a local function.
  • Applying an exported function (Mod:Name(), apply(Mod, Name, [])) is about twice as expensive as calling a fun, or about six times as expensive as calling a local function.
    DocLink: http://www.erlang.org/doc/efficiency_guide/functions.html


概念明确

   对于上面的结论,明确一下上面表中 跨模块调用这个概念在Erlang中常用的表达方式:
In the first form of function calls, ExprM:ExprF(Expr1,...,ExprN), each of ExprM and ExprF must be an atom or an expression that evaluates to an atom. The function is said to be called by using the  fully qualified function name. This is often referred to as a  remote or  external function call

速度差异因何而来

      fun包含或者间接包含了实现了该方法的指针调用不涉及hash-table的查询,apply/3必须要在HashTable中查找funtion对应的Code实现,所以通常比直接调用或者fun调用速度要慢. 
     

编译时优化

   在参数个数确定的时候,apply/3的调用会在编译时被优化为m:f(a)形式的external function call.通过一段代码看一下:
复制代码
a() -> 
    M=erlang,
    F=now,
    apply(M,F,[]).

b(M,F,A) -> 
   apply(M,F,A).

c(M,F) ->
   apply(M,F,[a,b,c]).
   
d(M)->
   apply(M,do_something,[]).
复制代码

  我们添加to_core参数,看一下编译出来的Core Erlang代码:

复制代码
'a'/0 =
    %% Line 33
    fun () ->
     %% Line 36
     call 'erlang':'now'
         ()
'b'/3 =
    %% Line 38
    fun (_cor2,_cor1,_cor0) ->
     %% Line 39
     call 'erlang':'apply'
         (_cor2, _cor1, _cor0)
'c'/2 =
    %% Line 41
    fun (_cor1,_cor0) ->
     %% Line 42
     call _cor1:_cor0
         ('a', 'b', 'c')
'd'/1 =
    %% Line 44
    fun (_cor0) ->
     %% Line 45
     call _cor0:'do_something'
         ()
 
复制代码

   可以看到在参数个数确定的情况下,apply/3的调用已经都被优化为mfa的调用方式.

   Erlang代码加载自后的调用方式细节需要找资料深入研究一下,估计是在Code Server相关的代码中,待续
目录
相关文章
|
15天前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `<`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
26天前
|
JavaScript 前端开发
JavaScript函数是代码复用的关键。使用`function`创建函数
【6月更文挑战第22天】JavaScript函数是代码复用的关键。使用`function`创建函数,如`function sayHello() {...}`或`function addNumbers(num1, num2) {...}`。调用函数如`sayHello()`执行其代码,传递参数按值进行。函数可通过`return`返回值,无返回值默认为`undefined`。理解函数对于模块化编程至关重要。
24 4
|
20天前
|
运维 负载均衡 Serverless
函数计算产品使用问题之yaml如果写多个function,可不可以yaml在构建的时候能构建多个函数
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
1月前
|
JSON 数据格式
setInterval函数的function与()=>区别——解决Cannot readproperty‘XXXXXXX‘of undefined异常
setInterval函数的function与()=>区别——解决Cannot readproperty‘XXXXXXX‘of undefined异常
14 0
|
2月前
|
JavaScript 前端开发
在JavaScript中,函数原型(Function Prototype)是一个特殊的对象
【5月更文挑战第11天】JavaScript中的函数原型是一个特殊对象,它为所有函数实例提供共享的方法和属性。每个函数在创建时都有一个`prototype`属性,指向原型对象。利用原型,我们可以向所有实例添加方法和属性,实现继承。例如,我们定义一个`Person`函数,向其原型添加`greet`方法,然后创建实例`john`和`jane`,它们都能调用这个方法。尽管可以直接在原型上添加方法,但推荐在构造函数内部定义以封装数据和逻辑。
35 2
|
1月前
|
JavaScript 编译器 前端开发
11.【TypeScript 教程】函数(Function)
11.【TypeScript 教程】函数(Function)
11 0
|
2月前
|
存储 算法 对象存储
【C++入门到精通】function包装器 | bind() 函数 C++11 [ C++入门 ]
【C++入门到精通】function包装器 | bind() 函数 C++11 [ C++入门 ]
35 1
|
2月前
|
存储
function(函数)
在 Lua 中,函数作为第一类值可存储于变量,如示例所示:`factorial1` 和 `factorial2` 存储相同函数。此外,函数可作为参数传递,如 `testFun` 接收一个表和一个匿名函数,该匿名函数在迭代中处理键值对,输出 `key1=val1` 和 `key2=val2`。
|
2月前
|
JavaScript 前端开发
【专栏】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表
【4月更文挑战第29天】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表。它接受两个参数:上下文对象和参数数组。理解`apply`有助于深入JS运行机制。文章分三部分探讨其原理:基本概念和用法、工作原理详解、实际应用与注意事项。在应用中要注意性能、参数类型和兼容性问题。`apply`可用于动态改变上下文、传递参数数组,甚至模拟其他语言的调用方式。通过深入理解`apply`,能提升代码质量和效率。
|
2月前
|
Serverless 应用服务中间件 数据安全/隐私保护
Serverless 应用引擎操作报错合集之在阿里函数计算中,函数执行超时,报错Function time out after如何解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。

热门文章

最新文章