Swift言語に非常に新しい
私はC++のようにインライン関数を宣言したかったので、私の楽しい宣言は
func MyFunction(param: Int) -> Int {
...
...
...
}
そして私はtiのような何かをしたい
inline func MyFunction(param: Int) -> Int {
...
...
...
}
Webで検索しようとしましたが、関連するものは何も見つかりませんでした。おそらくインラインキーワードはありませんが、関数をインライン化する別の方法があるかもしれません。
どうもありがとう :)
Swift 1.2には、never
および_@inline
_をパラメーターとして持つ___always
_属性が含まれます。詳細については、 here を参照してください。
前に述べたように、関数を@inline(__always)
として明示的に宣言する必要はほとんどありません。なぜなら、Swiftは関数をインライン化するタイミングに関してかなり賢明です。一部のコードでは必要になる場合があります。
answer へのすべてのクレジット、 link からの情報を要約するだけです。
関数をインラインにするには、関数の前に@inline(__always)
を追加するだけです:
_@inline(__always) func myFunction() {
}
_
ただし、さまざまな可能性について検討し、学ぶ価値があります。インライン化には3つの方法があります。
@inline(__always)
を追加して、この動作を実現します。 「機能がかなり小さく、アプリの実行速度が速い場合」を使用します。@inline(never)
を追加することで実現できます。 「関数が非常に長く、コードセグメントサイズの増加を避けたい場合」を使用します。Swift 4.2で導入された_@inlinable
_および_@usableFromInline
_属性を使用する必要があるという問題に遭遇したため、私の経験を皆さんと共有したいと思います。
ただし、私たちのコードベースには、他のモジュールをリンクするAnalytics Facadeモジュールがあります。
App Target-> Analytics Facadeモジュール-> Reportingモジュール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)
}
_