実際、一部のOpenGL関連のコードをテストしているときに、プライベートフィールドでfinal修飾子を使用すると、パフォーマンスが低下することがわかりました。これが私がテストしたクラスの始まりです:
public class ShaderInput {
private /* final */ float[] input;
private /* final */ int[] strides;
public ShaderInput()
{
this.input = new float[10];
this.strides = new int[] { 0, 4, 8 };
}
public ShaderInput x(int stride, float val)
{
input[strides[stride] + 0] = val;
return this;
}
// more stuff ...
そして、これは私がさまざまな選択肢のパフォーマンスをテストするために使用したメソッドであり、その中でShaderInputクラスは次のとおりです。
public static void test4()
{
int arraySize = 10;
float[] fb = new float[arraySize];
for (int i = 0; i < arraySize; i++) {
fb[i] = random.nextFloat();
}
int times = 1000000000;
for (int i = 0; i < 10; ++i) {
floatVectorTest(times, fb);
arrayCopyTest(times, fb);
shaderInputTest(times, fb);
directFloatArrayTest(times, fb);
System.out.println();
System.gc();
}
}
3回目の反復の後、VMがウォームアップしたため、最後のキーワードなしで次の数字が一貫して得られました。
Simple array copy took : 02.64
System.arrayCopy took : 03.20
ShaderInput took : 00.77
Unsafe float array took : 05.47
finalキーワード:
Simple array copy took : 02.66
System.arrayCopy took : 03.20
ShaderInput took : 02.59
Unsafe float array took : 06.24
ShaderInputテストの図に注意してください。
フィールドをパブリックにするかプライベートにするかは関係ありませんでした。
ちなみに、さらにいくつかの不可解な点があります。ShaderInputクラスは、finalキーワードを使用しても、他のすべてのバリアントよりも優れています。これは注目に値するb / cです。基本的にはfloat配列をラップするクラスですが、他のテストは配列を直接操作します。これを理解する必要があります。ShaderInputの流暢なインターフェイスと関係がある可能性があります。
また、System.arrayCopyは、forループで単純に1つの配列から別の配列に要素をコピーするよりも、小さな配列の方が明らかに明らかに低速です。そして、sun.misc.Unsafe(および直接java.nio.FloatBuffer、ここには示されていません)を使用すると、非常に小さなパフォーマンスを発揮します。