Làm thế nào để tránh trùng lặp mã liên quan đến các loại nguyên thủy?


9

Lý lịch

Một luồng đầu vào bit được hỗ trợ bởi một mảng byte. Có một số phương thức đọc từ mảng byte đó thành các mảng nguyên thủy bị ép buộc khác nhau.

Vấn đề

Có mã trùng lặp. Java thiếu khái quát về các kiểu nguyên thủy, vì vậy có lẽ việc lặp lại là không thể tránh khỏi.

Mã lặp đi lặp lại là rõ ràng trong các phương pháp sau:

@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;
}

Lưu ý làm thế nào final byte[] outliên quan đến readByte(bits)chỉ là final short[] outliên quan đến readShort(bits). Những mối quan hệ này là mấu chốt của vấn đề.

Câu hỏi

Làm thế nào để sao chép có thể được loại bỏ, nếu hoàn toàn không gây ra một cú đánh hiệu suất đáng kể (ví dụ: bằng cách tự động đóng hộp)?

Liên quan


6
Không, không có gì bạn có thể làm ở đó. Sao chép là lựa chọn duy nhất.
Andy Turner

Sử dụng bộ sưu tập nguyên thủy của bên thứ ba
Vince Emigh

1
Java lacks generics on primitive types, so perhaps the repetition is unavoidable.Vâng . )
markspace

3
Ngoài ra, (chỉ cần nhớ điều này) nếu bạn đang đọc các nguyên hàm hàng loạt như mã của bạn dường như chỉ ra, sử dụng ByteBuffercác phương thức như asDoubleBuffer()hoặc asShortBuffer()sẽ giảm tải một số công việc ở mức thấp nhất. docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/ Kẻ
markspace

1
Lưu ý rằng có một số nỗ lực để mang lại sự hỗ trợ chung chung cho Java, List<int>v.v. Phát hành trong khoảng 2 - 5 năm hoặc lâu hơn. Nó được gọi là Dự án Valhalla.
Zabuzard

Câu trả lời:


2

Nếu bạn đang đọc các nguyên hàm hàng loạt như mã của bạn dường như chỉ ra, sử dụng các phương thức ByteBuffer như asDoubleBuffer () hoặc asShortBuffer () sẽ giảm tải một số công việc ở mức thấp nhất.

Thí dụ:

   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`
   }

(Biên dịch mã nhưng không được kiểm tra!)


0

Một khả năng, sẽ phải chịu một hình phạt hiệu năng, là sử dụng java.lang.reflect.Arrayđể coi mảng là một Đối tượng sau đó cho phép sử dụng lại cùng một mã trên tất cả các phương thức đọc.

@FunctionalInterface
public interface BitArrayReader {
    Object read(int bits);
}

private long readPrimitive(
        final Object out, final int offset, final int count, final int bits,
        final BitArrayReader reader) {
    final int total = offset + count;

    assert out != null;
    assert total <= Array.getLength(out);

    final long startPosition = position();

    for (int i = offset; i < total; i++) {
        Array.set(out, i, reader.read(bits));
    }

    return position() - startPosition;
}

@Override
public long readBooleans(boolean[] out, int offset, int count, int bits) {
    return readPrimitive(out, offset, count, bits, this::readBoolean);
}

Sự trùng lặp đã được giải quyết với chi phí của một số hiệu suất, thiếu một chút an toàn kiểu thời gian biên dịch và sử dụng sự phản chiếu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.