This class does need to be revisted for performance, if you have some
optimisations feel free to send over a pull request.
Regards,
Darran Lofthouse.
On 05/06/14 20:30, Bernd Eckenfels wrote:
Hello,
I was a bit confused about the use of UTF-8 for converting a number to
bytes, but when I looked more closely, it is even more confusing why a
decimal number is used and converted here at all. If I understand it
right the format of the bytes and the length is unconstrained? I would
recommend to use 7 byte array with binary content. But even using Hex
or radix=36 strings would reduce the byte[] size without losing
entropy.
private Nonce createNewNonce(NonceHolder previousNonce) {
byte[] prefix = new byte[8];
random.nextBytes(prefix);
long timeStamp = System.currentTimeMillis();
byte[] now = Long.toString(timeStamp).getBytes(UTF_8);
String nonce = createNonce(prefix, now);
->
byte[] now =
Long.toString(timeStamp,36).getBytes(StandardCharsets.ISO_8859_1)
This makes the byte array shorter and the conversion slightly faster,
here are the timing for the various byte encoders on different string
formats (base-10,16,32,36) (8threads):
Benchmark (number) Mode Samples Score
Score error Units
n.e.t.l.MyBenchmark.testGetBytesASCII 1401994160926 thrpt 80 4932,143
41,752 ops/ms
n.e.t.l.MyBenchmark.testGetBytesASCII 1466d5d2b1e thrpt 80 5270,165
64,343 ops/ms
n.e.t.l.MyBenchmark.testGetBytesASCII 18pmlqaou thrpt 80 5521,322
119,856 ops/ms
n.e.t.l.MyBenchmark.testGetBytesASCII hw2f4hzy thrpt 80 5929,315
62,562 ops/ms
n.e.t.l.MyBenchmark.testGetBytesBase 1401994160926 thrpt 80 154669,919
3845,919 ops/ms
n.e.t.l.MyBenchmark.testGetBytesBase 1466d5d2b1e thrpt 80 155290,761
1678,557 ops/ms
n.e.t.l.MyBenchmark.testGetBytesBase 18pmlqaou thrpt 80 152989,174
5648,101 ops/ms
n.e.t.l.MyBenchmark.testGetBytesBase hw2f4hzy thrpt 80 154360,497
3022,226 ops/ms
n.e.t.l.MyBenchmark.testGetBytesDefault 1401994160926 thrpt 80 2319,440
47,902 ops/ms
n.e.t.l.MyBenchmark.testGetBytesDefault 1466d5d2b1e thrpt 80 2648,794
29,700 ops/ms
n.e.t.l.MyBenchmark.testGetBytesDefault 18pmlqaou thrpt 80 3098,998
36,169 ops/ms
n.e.t.l.MyBenchmark.testGetBytesDefault hw2f4hzy thrpt 80 3364,678
33,274 ops/ms
n.e.t.l.MyBenchmark.testGetBytesLATIN1 1401994160926 thrpt 80 5202,078
189,594 ops/ms
n.e.t.l.MyBenchmark.testGetBytesLATIN1 1466d5d2b1e thrpt 80 6166,294
64,541 ops/ms
n.e.t.l.MyBenchmark.testGetBytesLATIN1 18pmlqaou thrpt 80 6677,003
130,301 ops/ms
n.e.t.l.MyBenchmark.testGetBytesLATIN1 hw2f4hzy thrpt 80 6293,458
331,745 ops/ms
n.e.t.l.MyBenchmark.testGetBytesLower 1401994160926 thrpt 80 10332,605
114,527 ops/ms
n.e.t.l.MyBenchmark.testGetBytesLower 1466d5d2b1e thrpt 80 10173,196
120,769 ops/ms
n.e.t.l.MyBenchmark.testGetBytesLower 18pmlqaou thrpt 80 10392,109
150,898 ops/ms
n.e.t.l.MyBenchmark.testGetBytesLower hw2f4hzy thrpt 80 10584,135
140,522 ops/ms
n.e.t.l.MyBenchmark.testGetBytesUTF8 1401994160926 thrpt 80 4998,594
115,126 ops/ms
n.e.t.l.MyBenchmark.testGetBytesUTF8 1466d5d2b1e thrpt 80 5184,154
72,303 ops/ms
n.e.t.l.MyBenchmark.testGetBytesUTF8 18pmlqaou thrpt 80 5395,096
98,476 ops/ms
n.e.t.l.MyBenchmark.testGetBytesUTF8 hw2f4hzy thrpt 80 5212,183
142,887 ops/ms
(Lower=loop over char array and use lower byte)
However I wonder if longToLower7Bytes(now) would be even more efficient?
Both changes needs to be reflected in verifyUnknownNonce() as well.
This would benefit from a byte nonce as well, as you could for example
not anymore trigger NumberFormatException with invalid nonces.
Want me to provide a binary version? How would the compatibility be
handled? (Using base10+ASCII is compatible, all other changes not). The native version
minimizes the GC load as well:
Benchmark (number) Mode Samples Score
Score error Units
n.e.t.l.MyBenchmark.testGetBytesNative 1401994160926 thrpt 80 31669,314
260,181 ops/ms
n.e.t.l.MyBenchmark.testGetBytesString 1401994160926 thrpt 80 2621,683
38,270 ops/ms
@GenerateMicroBenchmark
public byte[] testGetBytesNative() {
byte[] res = new byte[8];
long num = number;
for(int i=7;i>=0;i--)
{
res[i] = (byte)(num & 255);
num >>= 8;
}
return res;
}
@GenerateMicroBenchmark
public byte[] testGetBytesString() {
return Long.toString(number).getBytes(StandardCharsets.ISO_8859_1);
}
Gruss
Bernd
_______________________________________________
undertow-dev mailing list
undertow-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/undertow-dev