İlkel türlerle ilgili kodun kopyalanmasını nasıl önleyebilirim?


9

Arka fon

Bir bit giriş akışı bir bayt dizisiyle desteklenir. Bu bayt dizisinden çeşitli zorlanmış ilkel dizilere okunan birkaç yöntem vardır.

Sorun

Yinelenen kod var. Java, ilkel türlerde jeneriklerden yoksundur, bu nedenle tekrarlama kaçınılmazdır.

kod

Yinelenen kod aşağıdaki yöntemlerde belirgindir:

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

Not nasıl final byte[] outilgilidir readByte(bits)tıpkı final short[] outilgilidir readShort(bits). Bu ilişkiler sorunun temelini oluşturur.

Soru

Önemli bir performans isabetine girmeden (örneğin, otomatik boks ile), çoğalma, hiç nasıl ortadan kaldırılabilir?

İlişkili


6
Hayır, orada yapabileceğiniz hiçbir şey yok. Tek seçenek çoğaltmadır.
Andy Turner

Üçüncü taraf ilkel bir koleksiyon kullanın
Vince Emigh

1
Java lacks generics on primitive types, so perhaps the repetition is unavoidable.Evet. (Genellikle bir sorun değildir, çünkü bir programın birkaç farklı ilkelden daha fazlasına ihtiyaç duyması nadirdir. Ayrıca, bir sınıfın içine ilkel koyarak ve nesne serileştirmesi kullanarak bunu "düzeltebilirsiniz", ancak bu nispeten yavaş olabilir. )
markspace

3
Ayrıca, (sadece bunu hatırladım) kodunuz gibi toplu ilkelleri okuyorsanız , en düşük düzeyli çalışmalardan bazıları ByteBuffergibi asDoubleBuffer()veya bunları asShortBuffer()kullanacak yöntemleri kullanmak gibi görünüyor . docs.oracle.com/tr/java/javase/11/docs/api/java.base/java/nio/…
markspace

1
Java, List<int>vb. İlkel jenerik destek getirmek için bazı çabalar olduğunu unutmayın . Belki 2-5 yıl içinde serbest bırakın. Buna Project Valhalla denir.
Zabuzard

Yanıtlar:


2

Kodunuz gibi toplu ilkelleri okuyorsanız, asDoubleBuffer () veya asShortBuffer () gibi ByteBuffer yöntemlerini kullanmak , en düşük düzeydeki işlerden bazılarını boşaltacaktır .

Misal:

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

(Kod derlenir, ancak test edilmez!)


0

Bir performans cezasına neden olacak bir olasılık, java.lang.reflect.Arraydiziyi bir Nesne gibi işlemek için kullanmaktır ve daha sonra aynı kodu tüm okuma yöntemlerinde yeniden kullanmaya izin verir.

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

Çoğaltma, bazı performans, küçük bir derleme zamanı türü güvenliği eksikliği ve yansıma kullanımı pahasına ele alınmıştır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.