効率のためにクラスの外部から直接IVARアクセスを使用することができますか?
-
28-10-2019 - |
質問
クラスの外側からivarsにアクセスするために、プロパティを持つクラスを定義できます。
また、myInst-> ivar構文を使用して、c構造ファッションでアクセスすることもできます。
C ++では、アクセサーズと一緒に行きますが、Objective-Cでは、直接アクセスしたい場合があります。メッセージは、C ++メソッドのようにメッセージが入っていないため、いくつかのコンテキストで重要なアクセサに大きなパフォーマンスヒットが発生します。
たとえば、Scalarと呼ばれるIVARとその上で定義されたプロパティを備えたクラスで。スカラーは単純なフロート値です:
-(void) doWorkWithMyClass:(MyClass*)myinst
{
// array and other locals declaration omitted
for (int i = 0; i < reallyBigX; i++) {
result += [myinst scalar] * array[i];
[myinst computeNextScalar:i];
}
}
myinst scalar]をmyinst-> scalarに変更すると、メソッドはより速く実行されます。アクセサとの呼び出しを使用すると、このループでCPUの大部分を占めるためです。
C ++と同様に、私は直接IVARアクセスが一般的に落胆していることを理解していますが、この文脈では、速度が重要な場合、それは受け入れられますか?そうでない場合、Objective-Cクラスをまだ使用するより優先された方法はありますか?
解決
パフォーマンスに大きな影響を与えると、多くのことが受け入れられるようになりますが、あなたが与えている例では、より良い解決策があるようです。
まず、なぜそうしないのか [myinst computeNextScalar:i]
新しいスカラーを返しますか?それをした場合、それを取得する必要はなく、すべてがはるかに高速になります。
作業を移動することはできません myinst
?つまり、次のようなものを作成できません。
result = [myinst totalOverArray:array];
もしも reallyBigX
本当に大きいので、ここでaccelerate.frameworkを考慮する必要があります。あなたがしているように見える操作の種類のパフォーマンスを大幅に改善することができます。 (Accelerate Frameworkでパフォーマンステストを行う必要があります。一部の操作では大幅に遅くなる可能性がありますが、これはより速いかもしれません。)
最後に、Objective-Cを検討してください get...
パターン。このように見えます:
int *scalars = calloc(reallyBigX, sizeof(int));
[myinst getScalars:scalars range:NSMakeRange(0, reallyBigX)];
for (int i = 0; i < reallyBigX; i++) {
result += scalars[i] * array[i];
}
free(scalars);
ところで、上記は間違いなくの候補者です vDSP_dotpr()
, 、パフォーマンステストをする必要があります。多くの場合、単純なループは同等のものよりも高速です vDSP
Sride = 1の場合は呼び出します(単純な増分を使用できるのではなく、単純な増分を使用できるため += stride
).
他のヒント
はい、それは受け入れられます: @public
, @private
, など、アクセス修飾子は、クラスの外部からのivarにアクセスする必要があるデザインをサポートするために部分的に導入されました。ただし、Ivarsに直接書き込むことは避けてください。