Skip to content

Commit

Permalink
Improvement | Improve performance of readLong function unrolling loop…
Browse files Browse the repository at this point in the history
… and using bitwise operators instead of additions (#763)

* Improve performance of readLong function unrolling loop and using bitwise
operators instead of additions

* Improve performance of readLong function unrolling loop and using bitwise
operators instead of additions + unit test

* Restrict writeLong method visibility
  • Loading branch information
robertonr authored and cheenamalhotra committed Aug 17, 2018
1 parent ddc1d94 commit 2c86309
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 14 deletions.
9 changes: 1 addition & 8 deletions src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3629,14 +3629,7 @@ void writeLong(long value) throws SQLServerException {
((Buffer) logBuffer).position(((Buffer) logBuffer).position() + 8);
}
} else {
valueBytes[0] = (byte) ((value >> 0) & 0xFF);
valueBytes[1] = (byte) ((value >> 8) & 0xFF);
valueBytes[2] = (byte) ((value >> 16) & 0xFF);
valueBytes[3] = (byte) ((value >> 24) & 0xFF);
valueBytes[4] = (byte) ((value >> 32) & 0xFF);
valueBytes[5] = (byte) ((value >> 40) & 0xFF);
valueBytes[6] = (byte) ((value >> 48) & 0xFF);
valueBytes[7] = (byte) ((value >> 56) & 0xFF);
Util.writeLong(value, valueBytes, 0);
writeWrappedBytes(valueBytes, 8);
}
}
Expand Down
35 changes: 29 additions & 6 deletions src/main/java/com/microsoft/sqlserver/jdbc/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,35 @@ static BigDecimal readBigDecimal(byte valueBytes[], int valueLength, int scale)
* @return long value as read from bytes.
*/
/* L0 */static long readLong(byte data[], int nOffset) {
long v = 0;
for (int i = 7; i > 0; i--) {
v += (long) (data[nOffset + i] & 0xff);
v <<= 8;
}
return v + (long) (data[nOffset] & 0xff);
return ((long) (data[nOffset + 7] & 0xff) << 56)
| ((long) (data[nOffset + 6] & 0xff) << 48)
| ((long) (data[nOffset + 5] & 0xff) << 40)
| ((long) (data[nOffset + 4] & 0xff) << 32)
| ((long) (data[nOffset + 3] & 0xff) << 24)
| ((long) (data[nOffset + 2] & 0xff) << 16)
| ((long) (data[nOffset + 1] & 0xff) << 8)
| ((long) (data[nOffset] & 0xff));
}

/**
* Writes a long to byte array.
*
* @param value
* long value to write.
* @param valueBytes
* the byte array.
* @param offset
* the offset inside byte array.
*/
static void writeLong(long value, byte valueBytes[], int offset) {
valueBytes[offset++] = (byte) ((value) & 0xFF);
valueBytes[offset++] = (byte) ((value >> 8) & 0xFF);
valueBytes[offset++] = (byte) ((value >> 16) & 0xFF);
valueBytes[offset++] = (byte) ((value >> 24) & 0xFF);
valueBytes[offset++] = (byte) ((value >> 32) & 0xFF);
valueBytes[offset++] = (byte) ((value >> 40) & 0xFF);
valueBytes[offset++] = (byte) ((value >> 48) & 0xFF);
valueBytes[offset] = (byte) ((value >> 56) & 0xFF);
}

/**
Expand Down
18 changes: 18 additions & 0 deletions src/test/java/com/microsoft/sqlserver/jdbc/UtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,22 @@ public void readGUIDtoUUID() throws SQLException {
assertEquals(expected, Util.readGUIDtoUUID(guid));
}

@Test
public void testLongConversions() {
writeAndReadLong(Long.MIN_VALUE);
writeAndReadLong(Long.MIN_VALUE / 2);
writeAndReadLong(-1);
writeAndReadLong(0);
writeAndReadLong(1);
writeAndReadLong(Long.MAX_VALUE / 2);
writeAndReadLong(Long.MAX_VALUE);
}

private void writeAndReadLong(long valueToTest) {
byte[] buffer = new byte[8];
Util.writeLong(valueToTest, buffer, 0);
long newLong = Util.readLong(buffer, 0);
assertEquals(valueToTest, newLong);
}

}

0 comments on commit 2c86309

Please sign in to comment.