我应该何时(也不应该)使用Scala的@inline注释?

时间:2022-09-10 23:51:55

I believe I understand the basics of inline functions: instead of a function call resulting in parameters being placed on the stack and an invoke operation occurring, the definition of the function is copied at compile time to where the invocation was made, saving the invocation overhead at runtime.

我相信我理解内联函数的基本原理:不使用函数调用而导致参数被放置在堆栈上和调用操作发生,函数的定义在编译时被复制到调用的地方,在运行时保存调用开销。

So I want to know:

所以我想知道:

  • Does scalac use smarts to inline some functions (e.g. private def) without the hints from annotations?

    scalac是否在没有注释提示的情况下使用smarts来内联某些函数(例如私有def) ?

  • How do I judge when it be a good idea to hint to scalac that it inlines a function?

    我怎么判断什么时候它是一个好主意,暗示它是一个函数?

  • Can anyone share examples of functions or invocations that should or shouldn't be inlined?

    任何人都可以共享应该或不应该内联的函数或调用的例子吗?

2 个解决方案

#1


32  

Never @inline anything whose implementation might reasonably change and which is going to be a public part of a library.

永远不要@inline任何其实现可能会发生合理变化的东西,而这将成为一个库的公共部分。

When I say "implementation change" I mean that the logic actually might change. For example:

当我说“实现改变”时,我的意思是逻辑实际上可能会改变。例如:

object TradeComparator extends java.lang.Comparator[Trade] {
  @inline def compare(t1 : Trade, t2 : Trade) Int = t1.time compare t2.time
}

Let's say the "natural comparison" then changed to be based on an atomic counter. You may find that an application ends up with 2 components, each built and inlined against different versions of the comparison code.

假设“自然比较”然后根据原子计数器变化。您可能会发现,一个应用程序最终会有两个组件,每个组件都构建并嵌入了不同版本的比较代码。

#2


0  

Personally, I use @inline for alias:

就个人而言,我使用@inline作为别名:

class A(param: Param){
  @inline def a = param.a
  def a2() = a * a
}

Now, I couldn't find a way to know if it does anything (I tried to jad the generated .class, but couldn't conclude anything).

现在,我找不到一种方法来知道它是否做了任何事情(我尝试使用生成的.class,但不能得出任何结论)。

My goal is to explicit what I want the compiler to do. But let it decide what's best, or simply do what it's capable of. If it doesn't do it, maybe later compiler version will.

我的目标是明确我希望编译器做什么。但是让它来决定什么是最好的,或者仅仅做它能做的。如果它不这样做,也许以后编译器版本会。

#1


32  

Never @inline anything whose implementation might reasonably change and which is going to be a public part of a library.

永远不要@inline任何其实现可能会发生合理变化的东西,而这将成为一个库的公共部分。

When I say "implementation change" I mean that the logic actually might change. For example:

当我说“实现改变”时,我的意思是逻辑实际上可能会改变。例如:

object TradeComparator extends java.lang.Comparator[Trade] {
  @inline def compare(t1 : Trade, t2 : Trade) Int = t1.time compare t2.time
}

Let's say the "natural comparison" then changed to be based on an atomic counter. You may find that an application ends up with 2 components, each built and inlined against different versions of the comparison code.

假设“自然比较”然后根据原子计数器变化。您可能会发现,一个应用程序最终会有两个组件,每个组件都构建并嵌入了不同版本的比较代码。

#2


0  

Personally, I use @inline for alias:

就个人而言,我使用@inline作为别名:

class A(param: Param){
  @inline def a = param.a
  def a2() = a * a
}

Now, I couldn't find a way to know if it does anything (I tried to jad the generated .class, but couldn't conclude anything).

现在,我找不到一种方法来知道它是否做了任何事情(我尝试使用生成的.class,但不能得出任何结论)。

My goal is to explicit what I want the compiler to do. But let it decide what's best, or simply do what it's capable of. If it doesn't do it, maybe later compiler version will.

我的目标是明确我希望编译器做什么。但是让它来决定什么是最好的,或者仅仅做它能做的。如果它不这样做,也许以后编译器版本会。