「単純な」コードを入力しているときにも、100%以上のCPUを経験しました。コードを構造化する方法で迅速なパーサーをより速くするためのいくつかの小さなトリック。
文字列で「+」コンカチネータを使用しないでください。私にとって、これは非常に迅速に遅さを引き起こします。新しい「+」はパーサーをクロールし、関数本体のどこかに新しい文字を追加するたびにコードを再解析する必要があります。
の代わりに:
var str = "This" + String(myArray.count) + " is " + String(someVar)
迅速に解析する方がはるかに効率的であるように見えるテンプレート構文を使用します。
var str = "This \(myArray.count) is \(someVar)"
このようにして、基本的にインライン変数「\(*)」を使用したstrlenには制限がないことに気付きます。
+ / *-を使用する計算がある場合は、それらを小さな部分に分割します。
の代わりに:
var result = pi * 2 * radius
使用する:
var result = pi * 2
result *= radius
見た目は効率的ではないかもしれませんが、Swiftパーサーはこの方法の方がはるかに高速です。数式が数学的に正しい場合でも、多くの演算を実行する必要がある場合、一部の数式はコンパイルされません。
いくつかの複雑な計算がある場合は、関数に入れます。このようにして、パーサーはそれを一度解析でき、関数本体で何かを変更するたびにそれを再解析する必要はありません。
関数本体に計算がある場合、型、構文などがまだ正しいかどうか、どういうわけか迅速なパーサーが毎回それをチェックするからです。計算の上で線が変化する場合は、計算/数式内の一部の変数が変更されている可能性があります。外部関数に配置すると、検証が1回行われ、swiftはそれが正しく、常に再解析されないことに満足しており、CPU使用率が高くなっています。
このようにして、入力中にキーを押すたびに100%から低CPUになりました。たとえば、関数本体にインラインで配置されたこの3行は、swiftparserをクロールさせる可能性があります。
let fullPath = "\(NSHomeDirectory())/Library/Preferences/com.apple.spaces.plist"
let spacesData = NSDictionary(contentsOfFile: fullPath )! // as Dictionary<String, AnyObject>
let spaces : AnyObject = spacesData["SpacesDisplayConfiguration"]!["Management Data"]!!["Monitors"]!![0]["Spaces"]!!
println ( spaces )
それをfuncに入れて後で呼び出すと、swiftparserの方がはるかに高速です
// some crazy typecasting here to silence the parser
// Autodetect of Type from Plist is very rudimentary,
// so you have to teach swift your types
// i hope this will get improved in swift in future
// would be much easier if one had a xpath filter with
// spacesData.getxpath( "SpacesDisplayConfiguration/Management Data/Monitors/0/Spaces" ) as Array<*>
// and xcode could detect type from the plist automatically
// maybe somebody can show me a more efficient way to do it
// again to make it nice for the swift parser, many vars and small statements
func getSpacesDataFromPlist() -> Array<Dictionary<String, AnyObject>> {
let fullPath = "\(NSHomeDirectory())/Library/Preferences/com.apple.spaces.plist"
let spacesData = NSDictionary(contentsOfFile: fullPath )! as Dictionary<String, AnyObject>
let sdconfig = spacesData["SpacesDisplayConfiguration"] as Dictionary<String, AnyObject>
let mandata = sdconfig["Management Data"] as Dictionary<String, AnyObject>
let monitors = mandata["Monitors"] as Array<Dictionary<String, AnyObject>>
let monitor = monitors[0] as Dictionary<String, AnyObject>
let spaces = monitor["Spaces"] as Array<Dictionary<String, AnyObject>>
return spaces
}
func awakeFromNib() {
....
... typing here ...
let spaces = self.getSpacesDataFromPlist()
println( spaces)
}
SwiftとXCode 6.1はまだ非常にバグが多いですが、これらの簡単なトリックに従うと、コードの編集が再び受け入れられるようになります。.hファイルを取り除き、よりすっきりした構文を使用するので、私は多くを迅速に好みます。"myVar as AnyObject"のように多くの型キャストが必要ですが、それは複雑なObjective-Cプロジェクトの構造と構文に比べて小さな悪です。
また、別の経験として、使用するのが楽しいSpriteKitを試しましたが、60 fpsで一定の再描画が必要ない場合は、非常に非効率的です。「スプライト」が頻繁に変更されない場合は、古いCALayersを使用する方がCPUにとってはるかに優れています。レイヤーの.contentsを変更しない場合、CPUは基本的にアイドルですが、SpriteKitアプリがバックグラウンドで実行されている場合、他のアプリでのビデオ再生が、60fpsの更新ループがハード制限されているために途切れ始める可能性があります。
コンパイル中にxcodeが奇妙なエラーを表示することがあるので、メニューの[Product]> [Clean]に移動して再度コンパイルすると、キャッシュのバグのある実装のようです。
xcodeがコードに行き詰まった場合の解析を改善するもう1つの優れた方法は、こちらの別のスタックオーバーフローの投稿に記載されています。基本的に、すべてのコンテンツを.swiftファイルから外部エディターにコピーし、関数ごとにコピーして、ボトルネックの場所を確認します。これは実際に、私のプロジェクトが100%のCPUでクレイジーになった後、xcodeを再び妥当な速度に戻すのに役立ちました。コードをコピーして戻している間、コードをリファクタリングして、関数本体を短くし、関数/式/式を単純なままにする(または複数の行に分割する)ことができます。