性能问题:在Java中将十六进制char转换为其数字值的最快方法?

我想将代表十六进制值(大写或小写)的char转换为字节,例如

'0'->0, '1' -> 1, 'A' -> 10, 'a' -> 10, 'f' -> 15 etc...

我将非常频繁地调用此方法,因此性能非常重要。是否有比使用预初始化HashMap<Character,Byte>从中获取值更快的方法?

似乎 在使用开关盒和Jon Skeet的直接计算解决方案之间是一个折衷-但是,开关盒解决方案似乎略有下降。

格雷格的数组方法胜出。这是各种方法的200,000,000次运行的性能结果(以毫秒为单位):

Character.getNumericValue:

8360

Character.digit:

8453

HashMap<Character,Byte>:

15109

Greg's Array Method:

6656

JonSkeet's Direct Method:

7344

Switch:

7281

多谢你们!

乔恩·斯基特(JonSkeet),您过去的竞争对手,在这里,;-)

public class ScratchPad {

private static final int NUMBER_OF_RUNS = 200000000;

static byte res;

static HashMap<Character, Byte> map = new HashMap<Character, Byte>() {{

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 < 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 < 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 < 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 < NUMBER_OF_RUNS; i++ ) {

res = getValueFromHashMap( i );

}

System.out.println( "HashMap<Character,Byte>:" );

System.out.println( System.currentTimeMillis()-time );

time = System.currentTimeMillis();

for( int i = 0; i < 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 < 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 >= '0' && c <= '9')

{

result = (byte)(c - '0');

}

if (c >= 'a' && c <= 'f')

{

result = (byte)(c - 'a' + 10);

}

if (c >= 'A' && c <= '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 < '0' || c > 'f') {

throw new IllegalArgumentException();

}

byte result = (byte)charValues[c-'0'];

if (res < 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] );

}

}

回答:

预初始化的数组将比HashMap更快。像这样:

int CharValues['f'-'0'+1] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, ... -1, 10, 11, 12, ...};

if (c < '0' || c > 'f') {

throw new IllegalArgumentException();

}

int n = CharValues[c-'0'];

if (n < 0) {

throw new IllegalArgumentException();

}

// n contains the digit value

您应该将此方法与其他方法进行基准比较,以确定哪种方法对您的应用程序最快。

以上是 性能问题:在Java中将十六进制char转换为其数字值的最快方法? 的全部内容, 来源链接: utcz.com/qa/406344.html

回到顶部