Tuesday, April 23, 2024
HomeJavaJDK 21: Picture Efficiency Enhancements - Java Code Geeks

JDK 21: Picture Efficiency Enhancements – Java Code Geeks


Introduction

In a earlier article, I talked about how serialization and file I/O efficiency was improved in JDK 21 due to the usage of VarHandleconstructs. The tactic employed there has now additionally been utilized to Java’s image-handling library making it sooner. Here’s what occurred:

Background

When packing/unpacking primitive values (corresponding to int and lengthy primitives) into/from a byte array, conversion was beforehand made utilizing specific bit shifting as proven within the ImageInputStreamImpl::readInt technique beneath:

public int readInt() throws IOException {
    if (learn(byteBuf, 0, 4) !=  4) {
        throw new EOFException();
    }

    if (byteOrder == ByteOrder.BIG_ENDIAN)  ((byteBuf[3] & 0xff) <<  0));
     else       // (2)
             ((byteBuf[1] & 0xff) <<  8) 
}
  1. Huge-endian unpacking through bit shifting
  2. Little-endian unpacking through bit shifting

The scheme used right here is analogous to what’s described in my earlier article so, I cannot dive into the main points once more. In brief, this technique is advanced and difficult for Java to completely optimize. Additionally, it’s exhausting to learn for us people.

Enhancements in JDK 21

In Java 21, conversions are as an alternative made with VarHandle constructs through the brand new jdk.inner.util.ByteArray class. Here’s what elements of the interior ByteArray class appear to be:

non-public static last VarHandle INT =
        MethodHandles.byteArrayViewVarHandle(int[], ByteOrder.BIG_ENDIAN);


static int getInt(byte[] b, int off) {
    return (int) INT.get(b, off);
}

Utilizing VarHandles means Java is ready to optimize strategies higher in comparison with specific bit shifting. Once more, you possibly can learn extra about how VarHandles work in my earlier article.

The category above handles big-endian. As pictures want to have the ability to deal with additionally little-endian a brand new class known as ByteArrayLittleEndianwas added. This implies the readInt() technique could be simplified and improved like this:

public int readInt() throws IOException {
    if (learn(byteBuf, 0, 4) !=  4) {
        throw new EOFException();
    }

    return (byteOrder == ByteOrder.BIG_ENDIAN)
            ? ByteArray.getInt(byteBuf, 0)
            : ByteArrayLittleEndian.getInt(byteBuf, 0);
}

Good! It appears a lot cleaner now.

Affected Lessons and Affect

The next courses have been immediately improved:

  • ImageInputStreamImpl
  • ImageOutputStreamImpl

The excellent news is that these courses present the muse for numerous different image-handling courses within the javax.imageio.stream package deal and maybe elsewhere (in any case, the above courses are within the public API).

This implies, in lots of circumstances, picture dealing with turns into sooner and all third-party libraries counting on any of the courses above (immediately or not directly) will even run sooner with no change in your software code.

Benchmarks

Within the benchmarks beneath, I’ve used Java 17 as a baseline which means that different Java 21 efficiency enhancements will even contribute to larger efficiency. I’ve run the benchmarks utilizing my Mac M1 aarch64 however the benchmarks can be found right here for anybody to run.

Graph 1 reveals the efficiency of the ImageInputStreamImpl::readInt technique for Java 17 and Java 21.

So, the throughput of the benchmarked technique has improved from about 579,800,000 bytes/s to round 639,000,000 bytes/s on my machine which is greater than a ten% enchancment! Not too dangerous!

Precise Utility Efficiency Enhance

How a lot sooner will your picture functions run beneath Java 21 in actuality? There is just one option to discover out: Run your individual code on JDK 21 right now by downloading a JDK 21 Early-Entry Construct.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments