Note that there are some explanatory texts on larger screens.

plurals
  1. POPerformance question: Fastest way to convert hexadecimal char to its number value in Java?
    text
    copied!<p>I want to convert from char representing a hexadecimal value (in upper or lower case) to byte, like</p> <pre><code>'0'-&gt;0, '1' -&gt; 1, 'A' -&gt; 10, 'a' -&gt; 10, 'f' -&gt; 15 etc... </code></pre> <p>I will be calling this method extremely often, so performance is important. Is there a faster way than to use a pre-initialized <code>HashMap&lt;Character,Byte&gt;</code> to get the value from?</p> <p><strong>Answer</strong></p> <p>It seems like <s>it's a tossup between using a switch-case and Jon Skeet's direct computing solution - the switch-case solution seems to edge out ever so slightly, though.</s> Greg's array method wins out. Here are the performance results (in ms) for 200,000,000 runs of the various methods:</p> <pre><code>Character.getNumericValue: 8360 Character.digit: 8453 HashMap&lt;Character,Byte&gt;: 15109 Greg's Array Method: 6656 JonSkeet's Direct Method: 7344 Switch: 7281 </code></pre> <p>Thanks guys!</p> <p><strong>Benchmark method code</strong></p> <p>Here ya go, JonSkeet, you old competitor. ;-)</p> <pre><code>public class ScratchPad { private static final int NUMBER_OF_RUNS = 200000000; static byte res; static HashMap&lt;Character, Byte&gt; map = new HashMap&lt;Character, Byte&gt;() {{ put( Character.valueOf( '0' ), Byte.valueOf( (byte )0 )); put( Character.valueOf( '1' ), Byte.valueOf( (byte )1 )); put( Character.valueOf( '2' ), Byte.valueOf( (byte )2 )); put( Character.valueOf( '3' ), Byte.valueOf( (byte )3 )); put( Character.valueOf( '4' ), Byte.valueOf( (byte )4 )); put( Character.valueOf( '5' ), Byte.valueOf( (byte )5 )); put( Character.valueOf( '6' ), Byte.valueOf( (byte )6 )); put( Character.valueOf( '7' ), Byte.valueOf( (byte )7 )); put( Character.valueOf( '8' ), Byte.valueOf( (byte )8 )); put( Character.valueOf( '9' ), Byte.valueOf( (byte )9 )); put( Character.valueOf( 'a' ), Byte.valueOf( (byte )10 )); put( Character.valueOf( 'b' ), Byte.valueOf( (byte )11 )); put( Character.valueOf( 'c' ), Byte.valueOf( (byte )12 )); put( Character.valueOf( 'd' ), Byte.valueOf( (byte )13 )); put( Character.valueOf( 'e' ), Byte.valueOf( (byte )14 )); put( Character.valueOf( 'f' ), Byte.valueOf( (byte )15 )); put( Character.valueOf( 'A' ), Byte.valueOf( (byte )10 )); put( Character.valueOf( 'B' ), Byte.valueOf( (byte )11 )); put( Character.valueOf( 'C' ), Byte.valueOf( (byte )12 )); put( Character.valueOf( 'D' ), Byte.valueOf( (byte )13 )); put( Character.valueOf( 'E' ), Byte.valueOf( (byte )14 )); put( Character.valueOf( 'F' ), Byte.valueOf( (byte )15 )); }}; static int[] charValues = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10, 11, 12, 13,14,15}; static char[] cs = new char[]{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F'}; public static void main(String args[]) throws Exception { long time = System.currentTimeMillis(); for( int i = 0; i &lt; NUMBER_OF_RUNS; i++ ) { res = getNumericValue( i ); } System.out.println( "Character.getNumericValue:" ); System.out.println( System.currentTimeMillis()-time ); time = System.currentTimeMillis(); for( int i = 0; i &lt; NUMBER_OF_RUNS; i++ ) { res = getDigit( i ); } System.out.println( "Character.digit:" ); System.out.println( System.currentTimeMillis()-time ); time = System.currentTimeMillis(); for( int i = 0; i &lt; NUMBER_OF_RUNS; i++ ) { try { res = getValueFromArray( i ); } catch (IllegalArgumentException e) { } } System.out.println( "Array:" ); System.out.println( System.currentTimeMillis()-time ); time = System.currentTimeMillis(); for( int i = 0; i &lt; NUMBER_OF_RUNS; i++ ) { res = getValueFromHashMap( i ); } System.out.println( "HashMap&lt;Character,Byte&gt;:" ); System.out.println( System.currentTimeMillis()-time ); time = System.currentTimeMillis(); for( int i = 0; i &lt; NUMBER_OF_RUNS; i++ ) { char c = cs[i%cs.length]; res = getValueFromComputeMethod( c ); } System.out.println( "JonSkeet's Direct Method:" ); System.out.println( System.currentTimeMillis()-time ); time = System.currentTimeMillis(); for( int i = 0; i &lt; NUMBER_OF_RUNS; i++ ) { res = getValueFromSwitch( i ); } System.out.println( "Switch:" ); System.out.println( System.currentTimeMillis()-time ); } private static byte getValueFromSwitch( int i ) { byte res; char ch = cs[i%cs.length]; switch( ch ) { case '0': res = 0; break; case '1': res = 1; break; case '2': res = 2; break; case '3': res = 3; break; case '4': res = 4; break; case '5': res = 5; break; case '6': res = 6; break; case '7': res = 7; break; case '8': res = 8; break; case '9': res = 9; break; case 'a': case 'A': res = 10; break; case 'b': case 'B': res = 11; break; case 'c': case 'C': res = 12; break; case 'd': case 'D': res = 13; break; case 'e': case 'E': res = 14; break; case 'f': case 'F': res = 15; break; default: throw new RuntimeException("unknown hex character: " + ch ); } return res; } private static byte getValueFromComputeMethod( char c ) { byte result = 0; if (c &gt;= '0' &amp;&amp; c &lt;= '9') { result = (byte)(c - '0'); } if (c &gt;= 'a' &amp;&amp; c &lt;= 'f') { result = (byte)(c - 'a' + 10); } if (c &gt;= 'A' &amp;&amp; c &lt;= 'F') { result = (byte)(c - 'A' + 10); } return result; } private static byte getValueFromHashMap( int i ) { return map.get( Character.valueOf( cs[i%cs.length] ) ).byteValue(); } private static byte getValueFromArray( int i ) { char c = cs[i%cs.length]; if (c &lt; '0' || c &gt; 'f') { throw new IllegalArgumentException(); } byte result = (byte)charValues[c-'0']; if (res &lt; 0) { throw new IllegalArgumentException(); } return result; } private static byte getDigit( int i ) { return (byte)Character.digit( cs[i%cs.length], 16 ); } private static byte getNumericValue( int i ) { return (byte)Character.getNumericValue( cs[i%cs.length] ); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload