मैं चार बाइट के लिए एक हेक्साडेसिमल मान (ऊपरी या निचली मामले में) का प्रतिनिधित्व करने से कन्वर्ट करने के लिए, की तरहप्रदर्शन प्रश्न: हेक्साडेसिमल चार को जावा में अपने मूल्य मान में परिवर्तित करने का सबसे तेज़ तरीका?
'0'->0, '1' -> 1, 'A' -> 10, 'a' -> 10, 'f' -> 15 etc...
मैं बहुत अक्सर इस विधि कॉल करेंगे चाहते हैं, इसलिए प्रदर्शन महत्वपूर्ण है। क्या मूल्य प्राप्त करने के लिए पूर्व-प्रारंभिक HashMap<Character,Byte>
का उपयोग करने से कहीं अधिक तेज़ तरीका है?
उत्तर
ऐसा लगता है जैसे कि यह एक स्विच मामले का उपयोग कर और जॉन स्कीट की प्रत्यक्ष कंप्यूटिंग समाधान के बीच एक tossup है - स्विच मामले समाधान हालांकि कभी तो थोड़ा बाहर भेजने के लिए, लगता है। ग्रेग की सरणी विधि जीत जाती है। विभिन्न विधियों के 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]);
}
}
पुस्तकालय कार्यों का उपयोग कर कोई प्रदर्शन समस्याएं थीं? यदि कोई नहीं है, तो Character.digit (char, radix) पर्याप्त होना चाहिए। – questzen
इस बेंचमार्क के साथ विचार करने की एक बात यह है कि सरणी अच्छी तरह से काम करेगी * जबकि यह कैश में है * - यह बहुत अच्छा है यदि आप एक ही बार में कई पुनरावृत्तियों कर रहे हैं। यदि आपको मुख्य मेमोरी से प्राप्त होने वाली सरणी की प्रतीक्षा करनी है, हालांकि, पूरी तरह से कम्प्यूटेशनल दृष्टिकोण तेज होगा। –
दूसरे शब्दों में: "यह निर्भर करता है" :) –