【问题标题】:Do all programming languages store the output of function calls?所有编程语言都存储函数调用的输出吗?
【发布时间】:2020-06-09 22:20:57
【问题描述】:

这是一个关于编程语言是否记住/存储函数调用的输出的一般问题。

假设我需要计算一个数量X,这取决于一些更简单的计算。比方说

X=sin(t)+cos(t)+(cos(t)-sin(t))^2.

天真地,我可以像上面那样计算X,调用sin(t) 两次,cos(t) 两次。

或者我可以打电话给sin(t)cos(t) 一次:

a=sin(t)
b=cos(t)

然后做

X=a+b+(b-a)^2

直觉上,第二种方法应该快两倍吧?所有编程语言都是这样吗?

我问是因为,在 Julia 中进行这样的计算时,我注意到计算更简单的数量一次而不是在它们出现在 X 的表达式中的每个点调用它们并不会改变运行时间。

【问题讨论】:

  • 谷歌搜索“纯”函数。
  • 请注意,您可以使用 Memoize.jl 实现这一目标

标签: performance memory julia


【解决方案1】:

这取决于你的编译器有多聪明,以及函数的属性。

首先,您的编译器需要弄清楚您是否调用了 sin(t) 两次。这并不太难。

其次,它需要让自己相信 t 对于每个调用都具有相同的值。例如,如果 t 是一个静态变量,并且您没有调用 sin(t) 而是调用了其他函数,则该函数调用可以修改 t,因此第二次调用 sin(t) 将具有不同的参数和 sin(t)必须调用两次。

第三,它需要说服自己,sin(t) 被调用一次还是两次都没有关系。 (这样的函数称为幂等)。例如,如果您调用了一个将消息写入日志文件的函数,那么编译器将不得不调用它两次,或者只将一条消息写入日志文件而不是两条。

【讨论】:

  • 底线:除非函数被特别标记为双重调用消除(通过添加pure 关键字或类似关键字),否则您必须假设编译器不会对此进行优化。 sin() 等数学函数相对可能有这样的标记。对于其他任何事情,显式缓存函数结果是程序员的工作。通常这也有助于使代码更具可读性。
猜你喜欢
  • 2013-05-24
  • 1970-01-01
  • 2019-11-15
  • 1970-01-01
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 2021-02-12
  • 2011-03-19
相关资源
最近更新 更多