gpt4 book ai didi

java - 性能问题 : Fastest way to convert hexadecimal char to its number value in Java?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:02:42 24 4
gpt4 key购买 nike

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

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

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

回答

这似乎是在使用 switch-case 和 Jon Skeet 的直接计算解决方案之间的折腾 - 不过,switch-case 解决方案似乎略有优势。 Greg 的数组方法胜出。以下是各种方法运行 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

您应该将此方法与其他方法(例如 Jon Skeet's 直接方法)进行基准测试,以确定哪种方法最适合您的应用。

关于java - 性能问题 : Fastest way to convert hexadecimal char to its number value in Java?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/221001/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com