Skip to content

Commit

Permalink
replace String.format with faster custom decimal to hex method
Browse files Browse the repository at this point in the history
  • Loading branch information
rudygt committed Sep 8, 2022
1 parent cee31d7 commit b0d7b26
Showing 1 changed file with 25 additions and 3 deletions.
28 changes: 25 additions & 3 deletions src/main/software/amazon/event/ruler/ComparableNumber.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package software.amazon.event.ruler;

import java.util.Locale;
import java.nio.ByteBuffer;

/**
* Represents a number, turned into a comparable string
Expand All @@ -9,7 +9,7 @@
* They are all treated as floating point
* They are turned into strings by:
* 1. Add 10**9 (so no negatives), then multiply by 10**6 to remove the decimal point
* 2. Format with the format string %014x" because hex string converted from 5e9*1e6=10e15 has 14 characters.
* 2. Format to a 14 char string left padded with 0 because hex string converted from 5e9*1e6=10e15 has 14 characters.
* Note: We use Hex because of a) it can save 3 bytes memory per number than decimal b) it aligned IP address radix.
* If needed, we can consider to use 32 or 64 radix description to save more memory,e.g. the string length will be 10
* for 32 radix, and 9 for 64 radix.
Expand Down Expand Up @@ -39,7 +39,29 @@ static String generate(final double f) {
throw new IllegalArgumentException("Value must be between " + -Constants.FIVE_BILLION +
" and " + Constants.FIVE_BILLION + ", inclusive");
}
return String.format("%014x", (long) (TEN_E_SIX * (Constants.FIVE_BILLION + f))).toUpperCase(Locale.ROOT);

return toHexStringSkippingFirstByte((long) (TEN_E_SIX * (Constants.FIVE_BILLION + f)));
}

private static final String HEXES = "0123456789ABCDEF";

private static byte[] longToByteBuffer(long value) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(value);
return buffer.array();
}

static String toHexStringSkippingFirstByte(Long value) {
byte[] raw = longToByteBuffer(value);
char[] chars = new char[14];
for (int i = 1; i < raw.length; i++) {
byte b = raw[i];
int pos = (i - 1) * 2;
chars[pos] = HEXES.charAt((b & 0xF0) >> 4);
chars[pos + 1] = HEXES.charAt((b & 0x0F));
}
return new String(chars);
}

}

0 comments on commit b0d7b26

Please sign in to comment.