私はソフトウェアの特定のコンポーネント (他の誰かが作成したもの) を拡張するように割り当てられました。Android 用に完全に Java で書かれています (私が知っているネイティブ/c++ コンポーネントはありません)。
コードに慣れてきたら、メソッド (レンダリング クラスの描画メソッド) に出会いました。このメソッドには、オブジェクトを更新する大きなループが含まれます (その後、別のメソッドが後でオブジェクトをレンダリングします)。メソッドの作成者は、ループの前に、すべて/ほとんどのメンバー変数と配列、および他のオブジェクトのフィールドをローカル変数にキャッシュしているように見えました。コードは次のようになります。
float[] coordArr = mCoordArr;
float[] texCoordArr = mTexCoordArr;
float[] cArray = mColArray;
// ... there are further locals too, I didn't copy all here
float[] color = mColor;
float r = color[0];
float g = color[1];
float b = color[2];
float a = color[3];
int texw = mTexW;
int texH = mTexH;
Font font = mFont;
float[] ccords = font.ccords;
float cf = font.cf;
float cu = font.cu;
int len = mCurLength;
// Update the objects
for (int i = 0; i < len; ++i) {
// A quite big loop body
// ... all locals are accessed from the loop
}
レンダリング コンポーネントはシングル スレッドであり、すべてのメンバー変数があります。
Java/Dalvik 逆アセンブラで確認したところ、バイトコード コメントには、メソッドが41のレジスタを使用していると書かれています。著者は、JIT を支援し、フィールド/配列アクセスの時間を節約するためにそれらをローカルにキャッシュしたと思いますが、これはパフォーマンスに反する多数のローカルではありませんか? たとえば、「レジスタープレッシャー」について聞いたことがあります。
必要がない場合 (つまり、現在のコードに問題がない場合) はコードを書き直したくありません。プロファイルを作成するには、コードを書き直す必要があります (それ以外の場合は、1 つのバージョンしか存在しないため、現在のコードは比べ物にならない…)。
「あまりにも」多くのローカルを使用することが推奨されない場合、超えてはならない「最適な」最大値はありますか? (もちろん、システムのスタック サイズがハード リミットであることは知っています。) その場合、ソフトウェアの他の部分も修正する必要があるかもしれません (元の作成者がすべてをローカルに入れるほど親切だった場合)。