ローカル変数、メンバー変数、他のオブジェクトのメンバー変数、ゲッターセッターのアクセス性能を比較するベンチマークを行ったところです。ベンチマークは、1000万回の反復でループ内の変数を増やします。出力は次のとおりです。
ベンチマーク: ローカル 101、メンバー 1697、外国人メンバー 151、ゲッター セッター 268
これは Motorola XOOM タブレットと Android 3.2 で行われました。数値は実行時間のミリ秒です。メンバー変数の偏差を説明できる人はいますか? 特に、他のオブジェクトのメンバー変数と比較した場合。これらの数値に基づいて、計算で値を使用する前にメンバー変数をローカル変数にコピーする価値があるようです。ところで、HTC One X と Android 4.1 で同じベンチマークを行ったところ、同じ偏差が示されました。
それらの数値は妥当ですか、それとも私が見落としている体系的なエラーはありますか?
ベンチマーク関数は次のとおりです。
private int mID;
public void testMemberAccess() {
// compare access times for local variables, members, members of other classes
// and getter/setter functions
final int numIterations = 10000000;
final Item item = new Item();
int i = 0;
long start = SystemClock.elapsedRealtime();
for (int k = 0; k < numIterations; k++) {
mID++;
}
long member = SystemClock.elapsedRealtime() - start;
start = SystemClock.elapsedRealtime();
for (int k = 0; k < numIterations; k++) {
item.mID++;
}
long foreignMember = SystemClock.elapsedRealtime() - start;
start = SystemClock.elapsedRealtime();
for (int k = 0; k < numIterations; k++) {
item.setID(item.getID() + 1);
}
long getterSetter = SystemClock.elapsedRealtime() - start;
start = SystemClock.elapsedRealtime();
for (int k = 0; k < numIterations; k++) {
i++;
}
long local = SystemClock.elapsedRealtime() - start;
// just make sure nothing loops aren't optimized away?
final int dummy = item.mID + i + mID;
Log.d(Game.ENGINE_NAME, String.format("BENCHMARK: local %d, member %d, foreign member %d, getter setter %d, dummy %d",
local, member, foreignMember, getterSetter, dummy));
}
編集:
各ループを関数に入れ、ランダムに100回呼び出しました。結果: ベンチマーク: ローカル 100、メンバー 168、外国人メンバー 190、ゲッター セッター 271 良さそうです。外部オブジェクトは、関数内ではなく、最終的なクラス メンバーとして作成されました。