[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相关的代码中,待续
目录
相关文章
|
6天前
|
JavaScript 前端开发
在JavaScript中,函数原型(Function Prototype)是一个特殊的对象
【5月更文挑战第11天】JavaScript中的函数原型是一个特殊对象,它为所有函数实例提供共享的方法和属性。每个函数在创建时都有一个`prototype`属性,指向原型对象。利用原型,我们可以向所有实例添加方法和属性,实现继承。例如,我们定义一个`Person`函数,向其原型添加`greet`方法,然后创建实例`john`和`jane`,它们都能调用这个方法。尽管可以直接在原型上添加方法,但推荐在构造函数内部定义以封装数据和逻辑。
18 2
|
6天前
|
存储 算法 对象存储
【C++入门到精通】function包装器 | bind() 函数 C++11 [ C++入门 ]
【C++入门到精通】function包装器 | bind() 函数 C++11 [ C++入门 ]
17 1
|
6天前
|
存储
function(函数)
在 Lua 中,函数作为第一类值可存储于变量,如示例所示:`factorial1` 和 `factorial2` 存储相同函数。此外,函数可作为参数传递,如 `testFun` 接收一个表和一个匿名函数,该匿名函数在迭代中处理键值对,输出 `key1=val1` 和 `key2=val2`。
|
6天前
|
JavaScript 前端开发
【专栏】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表
【4月更文挑战第29天】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表。它接受两个参数:上下文对象和参数数组。理解`apply`有助于深入JS运行机制。文章分三部分探讨其原理:基本概念和用法、工作原理详解、实际应用与注意事项。在应用中要注意性能、参数类型和兼容性问题。`apply`可用于动态改变上下文、传递参数数组,甚至模拟其他语言的调用方式。通过深入理解`apply`,能提升代码质量和效率。
|
6天前
|
Serverless 应用服务中间件 数据安全/隐私保护
Serverless 应用引擎操作报错合集之在阿里函数计算中,函数执行超时,报错Function time out after如何解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
25 4
|
6天前
|
资源调度 Serverless 计算机视觉
高斯函数 Gaussian Function
**高斯函数,或称正态分布,以数学家高斯命名,具有钟形曲线特征。关键参数包括期望值μ(决定分布中心)和标准差σ(影响分布的宽度)。当μ=0且σ²=1时,分布为标准正态分布。高斯函数广泛应用于统计学、信号处理和图像处理,如高斯滤波器用于图像模糊。其概率密度函数为e^(-x²/2σ²),积分结果为误差函数。在编程中,高斯函数常用于创建二维权重矩阵进行图像的加权平均,实现模糊效果。
26 1
|
6天前
|
算法 Serverless C语言
CMake函数和宏(function和macro):使用函数和宏提高代码可读性
CMake函数和宏(function和macro):使用函数和宏提高代码可读性
37 1
|
6天前
|
存储 安全 编译器
【C++ 包装器类 std::function 和 函数适配器 std::bind】 C++11 全面的std::function和std::bind的入门使用教程
【C++ 包装器类 std::function 和 函数适配器 std::bind】 C++11 全面的std::function和std::bind的入门使用教程
34 0
|
6天前
|
SQL Oracle 关系型数据库
Flink的表值函数(Table-Valued Function,TVF)是一种返回值是一张表的函数
【2月更文挑战第17天】Flink的表值函数(Table-Valued Function,TVF)是一种返回值是一张表的函数
25 1
|
7月前
|
存储 数据安全/隐私保护
均匀散列函数(Uniform Hash Function)
均匀散列函数(Uniform Hash Function)是一种将不同长度的输入数据映射到相同大小的输出数据的散列函数。均匀散列函数的主要特点是,对于相同的输入数据,无论其长度如何,都会得到相同的输出散列值。这种散列函数常用于数据结构的存储和查找,例如哈希表、散列表等。
111 3

热门文章

最新文章