JDK-6738521 : Speed up access to "unsigned" byte arrays
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 6
  • Priority: P5
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-08-19
  • Updated: 2011-02-16
  • Resolved: 2009-02-05
Related Reports
Duplicate :  
Description
A DESCRIPTION OF THE REQUEST :
When reading unsigned bytes from a byte array like this

int v = b[n]&0xff;

the server JIT compiler creates MOVSX and AND instructions to read and convert the byte value.
This is not optimal, using just MOVZX would be faster and in fact this is what the compiler does when reading "unsigned" shorts (i.e. s[n]&0xffff).
As a result reading "unsigned" data from byte arrays is slower than it needs to be and slower than reading from short arrays.

Judging from the output of the demo code this last worked on JDK1.2.2.

CPU: Intel Core2Duo 6750



JUSTIFICATION :
This is a simple optimization (IMHO) which would improve the speed noticeably.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
bytes[n]&0xff should be as fast a possible, faster than shorts[n]&0xffff

Output of the sample code:
1.828 secs 1.829 secs
1.828 secs 1.656 secs
1.844 secs 1.781 secs
1.828 secs 1.719 secs
1.828 secs 1.719 secs
(JDK 1.2.2)
ACTUAL -
Output of the sample code:
1.953 secs 2.734 secs
2.078 secs 2.735 secs
1.875 secs 2.344 secs
1.875 secs 2.343 secs
1.875 secs 2.328 secs
(JDK 1.6.0_07 server VM)

---------- BEGIN SOURCE ----------
	private final static short[] sa = new short[250000];
	private static int test_short()
	{
		final long start = System.currentTimeMillis();
		
		int v = 0;
		for(int y = 0; y < 8000; y++) {
			for(int k = 0; k < sa.length; k++) {
				v += (sa[k]&0xffff)+y;
			}
		}
		
		System.out.print((System.currentTimeMillis()-start)/1000f+" secs ");
		return(v);
	}

	private final static byte[] sb = new byte[250000];
	private static int test_byte()
	{
		final long start = System.currentTimeMillis();
		
		int v = 0;
		for(int y = 0; y < 8000; y++) {
			for(int k = 0; k < sb.length; k++) {
				v += (sb[k]&0xff)+y;
			}
		}
		
		System.out.println((System.currentTimeMillis()-start)/1000f+" secs ");
		return(v);
	}
	
	public static void main(String[] args)
	{
		int v = 0;
		for(int k = 0; k < 5; k++) {
			v += test_short();
			v += test_byte();
		}
	}

---------- END SOURCE ----------

Comments
SUGGESTED FIX I'm working on this in 6797305.
05-02-2009