Re: Optimizing Java method
Hi,
some suggestions (note that they may depend upon your hardware, os and
jvm)...
Benjamin White wrote:
public static byte[] stringToPack(String str) throws DataException {
int i; // string index
int j; // byte array index
boolean nibble_ordinal = false;
char ch1;
byte nibble;
int strlen = str.length();
byte[] pknum = new byte[16];
for (i = 0; i < 16; i++) { // initialize to zero
pknum[i] = 0;
}
This schould not be necessary and can be done within the loop below!
i = strlen - 1;
j = 15; /* byte index */
pknum[j] = 12; // start with positive sign
while (i > -1) {
ch1 = str.charAt(i);
It might (!) be faster to first get the complete char[] from the String
and then to iterate over it.
Of course it would of course be great (if possible) if the
method-signature would accept a char[] instead of a String.
Note that a loop with an increasing array-index is *much* faster in most
cases (due to processor-caches) - if your logic allows that!
switch (ch1) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
Here, an if might be faster (but might be slower as well - measure it):
if(c1>=0 && ch1<=9) {
...
} else if (...
An if-cascade, of course, is much faster if you know the statistical
probability of the cases. If e.g. you know, that 99% of all characters
are an '-', then put the corresponding if-statement at the beginning!
nibble = (byte) Character.getNumericValue(ch1);
if (nibble_ordinal) {
pknum[j] = (byte) (pknum[j] | nibble);
nibble_ordinal ^= true;
} else {
pknum[j] = (byte) (pknum[j] | nibble << 4);
nibble_ordinal ^= true;
--j;
}
--i; // get next char
break;
case ',':
case ' ':
case '.':
case '$':
case '+':
--i; // get next char
break;
case '-':
pknum[15] = (byte) (pknum[15] & 0xf0);
pknum[15] = (byte) (pknum[15] | 0x0d);
This is slow: Why not write the result in a temporary variable first:
byte tmp = (byte) (pknum[15] & 0xf0);
pknum[15] = (byte) (tmp | 0x0d);
....or even do it in one single line:
pknum[15] = (byte) ((pknum[15] & 0xf0)| 0x0d);
--i; // get next char
break;
default:
throw new DataException("Invalid decimal digit: " + ch1);
}
}
return (pknum);
}
And, of course, if you have to convert millions of Strings but there are
only a hand full of *different* Strings (perhaps 1000 or 100.000), then
it is often a good idea to initialize a (Hash)Map with the Strings as
key and the result as value and only lookup the results.
Hth,
Ingo