Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hex To String in Java Performance is too slow

I have the following method for my android program, written in Java.

The method takes in a string of hex and returns a string of the same text written in ascii.

public static String hexToString(String hex)
{
    StringBuilder sb = new StringBuilder();

    for (int count = 0; count < hex.length() - 1; count += 2)
    {
        String output = hex.substring(count, (count + 2));    //grab the hex in pairs

        int decimal = Integer.parseInt(output, 16);    //convert hex to decimal

        sb.append((char)decimal);    //convert the decimal to character
    }

    return sb.toString();
}

The method works fine, however my program is very time critical and this method is potentially being called tens of thousands of times. When analysing the slow bits of my program, this method takes up far too much time because of:

Integer.parseInt(output, 16);

and

hex.substring(count, (count + 2));

In the order of slowest first.

Does anyone know of a faster method of achieving the same thing?

like image 580
Pippa Rose Smith Avatar asked Aug 20 '12 14:08

Pippa Rose Smith


2 Answers

Don't create a new String on each iteration. One way to improve performance would be using a char array and applying math operations per character.

public static String hexToString(String hex) {
    StringBuilder sb = new StringBuilder();
    char[] hexData = hex.toCharArray();
    for (int count = 0; count < hexData.length - 1; count += 2) {
        int firstDigit = Character.digit(hexData[count], 16);
        int lastDigit = Character.digit(hexData[count + 1], 16);
        int decimal = firstDigit * 16 + lastDigit;
        sb.append((char)decimal);
    }
    return sb.toString();
}

More info about this method:

  • Character#digit

Also, if you're parsing the hex string in pairs, you can use a look up table as @L7ColWinters suggests:

private static final Map<String, Character> lookupHex = new HashMap<String, Character>();

static {
    for(int i = 0; i < 256; i++) {
        String key = Integer.toHexString(i);
        Character value = (char)(Integer.parseInt(key, 16));
        lookupHex.put(key, value);
    }
}

public static String hexToString(String hex) {
    StringBuilder sb = new StringBuilder();
    for (int count = 0; count < hex.length() - 1; count += 2) {
        String output = hex.substring(count, (count + 2));
        sb.append((char)lookupHex.get(output));
    }
    return sb.toString();
}
like image 156
Luiggi Mendoza Avatar answered Nov 02 '22 23:11

Luiggi Mendoza


What about this one...

public static String hexToString(final String str) {
 return new String(new BigInteger(str, 16).toByteArray());
}
like image 3
nullpotent Avatar answered Nov 02 '22 23:11

nullpotent