Antecedentes
Una secuencia de entrada de bits está respaldada por una matriz de bytes. Hay un puñado de métodos que leen de esa matriz de bytes en varias matrices primitivas forzadas.
Problema
Hay un código duplicado. Java carece de genéricos en los tipos primitivos, por lo que tal vez la repetición sea inevitable.
Código
El código repetitivo es evidente en los siguientes métodos:
@Override
public long readBytes(final byte[] out, final int offset, final int count, final int bits) {
final int total = offset + count;
assert out != null;
assert total <= out.length;
final long startPosition = position();
for (int i = offset; i < total; i++) {
out[i] = readByte(bits);
}
return position() - startPosition;
}
@Override
public long readShorts(final short[] out, final int offset, final int count, final int bits) {
final int total = offset + count;
assert out != null;
assert total <= out.length;
final long startPosition = position();
for (int i = offset; i < total; i++) {
out[i] = readShort(bits);
}
return position() - startPosition;
}
Tenga en cuenta cómo se final byte[] out
relaciona con readByte(bits)
lo que se final short[] out
relaciona con readShort(bits)
. Estas relaciones son el quid de la cuestión.
Pregunta
¿Cómo se puede eliminar la duplicación, en todo caso, sin incurrir en un impacto significativo en el rendimiento (por ejemplo, mediante autoboxing)?
Relacionado
java
arrays
code-duplication
Dave Jarvis
fuente
fuente
Java lacks generics on primitive types, so perhaps the repetition is unavoidable.
Sip. (Por lo general, no es un gran problema, ya que es raro que un programa necesite más que unas pocas primitivas diferentes. También puede "arreglar" esto poniendo primitivas dentro de una clase y usando la serialización de objetos, aunque eso puede ser relativamente lento. )ByteBuffer
métodos comoasDoubleBuffer()
oasShortBuffer()
descargará algunos de los trabajos de nivel más bajo. docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/…List<int>
etc. Lanzamiento en unos 2-5 años más o menos. Se llama Proyecto Valhalla.Respuestas:
Si está leyendo primitivas masivas como parece indicar su código, el uso de métodos ByteBuffer como asDoubleBuffer () o asShortBuffer () descargará algunos de los trabajos de nivel más bajo.
Ejemplo:
(¡El código se compila pero no se prueba!)
fuente
Una posibilidad, que incurrirá en una penalización de rendimiento, es usar
java.lang.reflect.Array
para tratar la matriz como un Objeto que luego permite reutilizar el mismo código en todos los métodos de lectura.La duplicación se ha abordado a costa de algún rendimiento, una falta menor de seguridad de tipo de tiempo de compilación y el uso de la reflexión.
fuente