En realidad, mientras probaba un código relacionado con OpenGL, descubrí que usar el modificador final en un campo privado puede degradar el rendimiento. Aquí está el comienzo de la clase que probé:
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 ...
Y este es el método que utilicé para probar el rendimiento de varias alternativas, entre las cuales la clase 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();
}
}
Después de la tercera iteración, con la VM calentada, obtuve constantemente estas cifras sin la palabra clave final:
Simple array copy took : 02.64
System.arrayCopy took : 03.20
ShaderInput took : 00.77
Unsafe float array took : 05.47
Con la palabra clave final:
Simple array copy took : 02.66
System.arrayCopy took : 03.20
ShaderInput took : 02.59
Unsafe float array took : 06.24
Tenga en cuenta las cifras para la prueba ShaderInput.
No importaba si hacía los campos públicos o privados.
Por cierto, hay algunas cosas más desconcertantes. La clase ShaderInput supera a todas las demás variantes, incluso con la palabra clave final. Esto es notable b / c, básicamente es una clase que envuelve una matriz flotante, mientras que las otras pruebas manipulan directamente la matriz. Tengo que resolver esto. Puede tener algo que ver con la interfaz fluida de ShaderInput.
Además, System.arrayCopy aparentemente es algo más lento para matrices pequeñas que simplemente copiar elementos de una matriz a otra en un bucle for. Y el uso de sun.misc.Unsafe (así como el java.nio.FloatBuffer directo, que no se muestra aquí) funciona abismalmente.