有没有办法在swift中声明内联函数?

时间:2015-01-10 20:46:41

标签: swift inline-functions

我对快速语言非常陌生

我想在c ++中声明一个内联函数 所以我的有趣宣言就像

func MyFunction(param: Int) -> Int {
...
...
...
}

我希望做一些像

这样的事情
inline func MyFunction(param: Int) -> Int {
...
...
...
}

我试图在网上搜索,但我找不到任何相关内容 也许没有内联关键字,但也许还有另一种内联函数的方法

非常感谢:)

3 个答案:

答案 0 :(得分:43)

Swift 1.2将包含@inline属性,never__always作为参数。有关详细信息,请参阅here

如前所述,您很少需要将函数显式声明为@inline(__always),因为Swift在何时内联函数方面相当明智。但是,在某些代码中可能不需要内联函数。

答案 1 :(得分:13)

所有归功于answer,只是总结来自link的信息。

要使函数内联,只需在函数前添加@inline(__always)

@inline(__always) func myFunction() {

}

然而,值得考虑和了解不同的可能性。内联有三种可能的方法:

  • 有时 - 确保有时内联函数。这是默认行为,您不必做任何事情! Swift编译器可能会自动将函数内联为优化。
  • 始终 - 确保始终内联该功能。通过在函数之前添加@inline(__always)来实现此行为。使用"如果您的功能相当小,并且您希望自己的应用运行得更快。"
  • 从不 - 确保永远不会内联该功能。这可以通过在函数之前添加@inline(never)来实现。使用"如果您的功能很长,并且您希望避免增加代码段大小。"

答案 2 :(得分:1)

我遇到了一个问题,我需要使用Swift 4.2中引入的@inlinable@usableFromInline属性,以便与您分享我的经验。

不过,让我直接解决这个问题,我们的代码库具有一个可链接其他模块的Analytics Facade模块。

App Target-> Analytics Facade模块->报告模块X。

Analytics Facade模块具有一个名为report(_ rawReport: EventSerializable)的功能,可以触发报告调用。此功能使用报告模块X中的实例为该特定报告模块X发送报告调用。

问题是,一旦用户启动该应用,多次调用report(_ rawReport: EventSerializable)函数来发送报告调用会产生不可避免的开销,从而给我们造成很多崩溃。

此外,如果在调试模式下将Optimisation level设置为None,要重现这些崩溃并不是一件容易的事。就我而言,只有将Optimisation level设置为Fastest, Smalles t甚至更高时,我才能重现它。

解决方案是使用@inlinable@usableFromInline

使用@inlinable@usableFromInline将函数的主体导出为模块接口的一部分,从而使优化器在从其他模块引用时可供优化器使用。

@usableFromInline属性将内部声明标记为模块二进制接口的一部分,从而允许将其从@inlinable代码中使用,而不必将其声明为模块源接口的一部分。

跨模块边界,运行时泛型会带来不可避免的开销,因为必须在函数之间传递经过修饰的类型元数据,并且必须使用各种间接访问模式来操纵泛型的值。对于大多数应用程序而言,与代码本身执行的实际工作相比,此开销可以忽略不计。

基于此框架构建的客户端二进制文件可以调用这些泛型函数,并且由于消除了抽象开销,因此在启用优化的情况下构建时可能会提高性能。

示例代码

@inlinable public func allEqual<T>(_ seq: T) -> Bool
    where T : Sequence, T.Element : Equatable {
        var iter = seq.makeIterator()
        guard let first = iter.next() else { return true }

        func rec(_ iter: inout T.Iterator) -> Bool {
            guard let next = iter.next() else { return true }
            return next == first && rec(&iter)
        }

        return rec(&iter)
}

More Info - Cross-module inlining and specialization