A bit input stream is backed by an array of bytes. There are a handful of methods that read from that byte array into various coerced primitive arrays.
There is duplicated code. Java lacks generics on primitive types, so perhaps the repetition is unavoidable.
The repetitious code is apparent in the following methods:
@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;
}
Note how final byte[] out
relates to readByte(bits)
just as final short[] out
relates to readShort(bits)
. These relations are the crux of the problem.
How can the duplication be eliminated, if at all, without incurring a significant performance hit (e.g., by autoboxing)?
Primitive types don’t convey any meaningful domain knowledge — so don't build your domain classes solely with these types. Obviously, you can’t avoid strings (though, technically not a primitive type), ints, doubles, and other primitive types entirely. They’re the fundamental building blocks for any piece of code and application.
What is duplicate code? Duplicate code as the name suggests is a repetition of a line or a block of code in the same file or sometimes in the same local environment. People might consider code duplication acceptable but in reality, it poses greater problems to your software than what you may have thought.
But it's opinion-based and coding style is subjective. Readability, project coding conventions, and team buy-in are equally important. The emphasis for reducing duplication is not at all for reducing lines of code, but for reducing the opportunity for bugs, and to make maintaining easier.
Since it is not always straight-forward and easy to remove duplicated code patterns and behavior, many programmers would arguably eliminate the structural code duplication and leave with that: Code available at release 0.2.0. Now, the code in v0.1.1 is definitely better than v0.1.0, but the patterns in the code are still duplicated.
If you're reading bulk primitives like your code seems to indicate, using ByteBuffer methods like asDoubleBuffer() or asShortBuffer() will offload some of the lowest level work.
Example:
public void readBytes( final byte[] out, final int offset, final int count, final ByteBuffer buffer ) {
buffer.get( out, offset, count ); // udates ByteBuffer `position` automatically
}
public void readShorts( final short[] out, final int offset, final int count, final ByteBuffer buffer ) {
ShortBuffer sb = buffer.asShortBuffer();
sb.get( out, offset, count ); // note that `count` reads two bytes for each `short`
}
(Code compiles but not tested!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With