Is there a way in swift to declare an inline function?

为君一笑 提交于 2019-11-27 14:21:15

问题


I'm very new to the swift language

I wanted to declare an inline function just like in c++ so my fun declaration is like

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

and I want ti do something like

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

I tried to search on the web but I didn't find anything relevant maybe there is no inline keyword but maybe there is another way to inline the function

Many thanks :)


回答1:


Swift 1.2 will include the @inline attribute, with never and __always as parameters. For more info, see here.

As stated before, you rarely need to declare a function explicitly as @inline(__always) because Swift is fairly smart as to when to inline a function. Not having a function inlined, however, can be necessary in some code.

Edit: Swift 5 added the @inlinable attribute. Make sure you read up about it, as there may be a couple of gotchas that might make in unusable. It's also only for functions/methods declared public, so it's meant for those wanting to expose inline stuff for those that link to your library.




回答2:


All credit to the answer, just summarizing the information from the link.

To make a function inline just add @inline(__always) before the function:

@inline(__always) func myFunction() {

}

However, it's worth considering and learning about the different possibilities. There are three possible ways to inline:

  • sometimes - will make sure to sometimes inline the function. This is the default behavior, you don't have to do anything! Swift compiler might automatically inline functions as an optimization.
  • always - will make sure to always inline the function. Achieve this behavior by adding @inline(__always) before the function. Use "if your function is rather small and you would prefer your app ran faster."
  • never - will make sure to never inline the function. This can be achieved by adding @inline(never) before the function. Use "if your function is quite long and you want to avoid increasing your code segment size."



回答3:


I came across an issue that i needed to use @inlinable and @usableFromInline attributes that were introduced in Swift 4.2 so i would like to share my experience with you.

Let me get straight to the issue though, Our codebase has a Analytics Facade module that links other modules.

App Target -> Analytics Facade module -> Reporting module X.

Analytics Facade module has a function called report(_ rawReport: EventSerializable) that fire the reporting calls, This function uses an instance from the reporting module X to send the reporting calls for that specific reporting module X.

The thing is, calling that report(_ rawReport: EventSerializable) function many times to send the reporting calls once the users launch the app creates unavoidable overhead that caused a lot of crashes for us.

Moreover it's not an easy task to reproduce these crashes if you are setting the Optimisation level to None on the debug mode. In my case i was able only to reproduce it when i set the Optimisation level to Fastest, Smallest or even higher.

The solution was to use @inlinable and @usableFromInline.

Using @inlinable and @usableFromInline export the body of a function as part of a module's interface, making it available to the optimiser when referenced from other modules.

The @usableFromInline attribute marks an internal declaration as being part of the binary interface of a module, allowing it to be used from @inlinable code without exposing it as part of the module's source interface.

Across module boundaries, runtime generics introduce unavoidable overhead, as reified type metadata must be passed between functions, and various indirect access patterns must be used to manipulate values of generic type. For most applications, this overhead is negligible compared to the actual work performed by the code itself.

A client binary built against this framework can call those generics functions and enjoy a possible performance improvement when built with optimisations enabled, due to the elimination of abstraction overhead.

Sample Code:

@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



来源:https://stackoverflow.com/questions/27881051/is-there-a-way-in-swift-to-declare-an-inline-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!