2010-02-04 11 views
16

कनवर्ट करें मैं स्पष्ट रूप से प्रतिनिधित्व का उपयोग कर फ़ाइल में लॉग इन करने के लिए, log4j में ASCII वर्णों वाले बाइट [] को पास करने का प्रयास कर रहा हूं। जब मैं बस बाइट में जाता हूं [] यह निश्चित रूप से एक वस्तु के रूप में माना जाता है और लॉग बहुत बेकार हैं। जब मैं उन्हें new String(byte[] data) का उपयोग करके स्ट्रिंग में बदलने की कोशिश करता हूं, तो मेरे आवेदन का प्रदर्शन कम हो जाता है।एएससीआईआई बाइट [] से स्ट्रिंग

मैं उन्हें कुशलता से कैसे पारित कर सकता हूं, बिना उन्हें तारों में परिवर्तित करने के लगभग 30us समय जुर्माना लगाए।

इसके अलावा, उन्हें बदलने के लिए इतना लंबा समय क्यों लगता है?

धन्यवाद।

संपादित

मैं जोड़ने चाहिए कि मैं विलंबता यहाँ optmising रहा हूँ - और हाँ, 30us एक फर्क पड़ता है! इसके अलावा, ये सरणी कुछ हद तक बाईट तक 100 से भिन्न होती हैं।

उत्तर

13

क्या आप क्या करना चाहते बाइट [] सरणी के देरी प्रसंस्करण है जब तक log4j का फैसला करता है यह वास्तव में संदेश लॉग इन करना चाहता है। इस तरह आप इसे DEBUG स्तर पर लॉग कर सकते हैं, उदाहरण के लिए, परीक्षण करते समय और फिर उत्पादन के दौरान इसे अक्षम करें। उदाहरण के लिए, आप:

final byte[] myArray = ...; 
Logger.getLogger(MyClass.class).debug(new Object() { 
    @Override public String toString() { 
     return new String(myArray); 
    } 
}); 

अब आप गति दंड का भुगतान नहीं करते जब तक आप वास्तव में डेटा प्रवेश करते है, क्योंकि toString विधि जब तक log4j का फैसला करता है यह वास्तव में संदेश प्रवेश करेंगे कहा जाता है नहीं है!

अब मुझे यकीन नहीं है कि "स्पष्ट प्रतिनिधित्व" से आपका क्या मतलब है, इसलिए मैंने माना है कि आप बाइट्स को डिफ़ॉल्ट वर्ण एन्कोडिंग के रूप में पुन: परिभाषित करके स्ट्रिंग में कनवर्ट करना चाहते हैं। अब यदि आप द्विआधारी डेटा से निपट रहे हैं, तो यह स्पष्ट रूप से बेकार है। उस मामले में मैं की तर्ज पर एक स्वरूपित स्ट्रिंग बनाने के लिए Arrays.toString(byte[]) उपयोग करने का सुझाव था

[54, 23, 65, ...] 
+2

अच्छा, एक एसिंक्रोनस लॉगर का उपयोग करके यह रूपांतरण को महत्वपूर्ण पथ से दूर ले जाता है। – jwoolard

16

ASCII कुछ किसी एक एन्कोडिंग कि इसलिए यह संभव है कोई गणित या तालिका लुकअप साथ UTF16 से/परिवर्तित किया जा सकता है मैन्युअल रूप से परिवर्तित:

String convert(byte[] data) { 
    StringBuilder sb = new StringBuilder(data.length); 
    for (int i = 0; i < data.length; ++ i) { 
     if (data[i] < 0) throw new IllegalArgumentException(); 
     sb.append((char) data[i]); 
    } 
    return sb.toString(); 
} 

लेकिन यकीन है कि यह वास्तव में ASCII है, या आप कचरा के साथ खत्म हो जाएगा सुनिश्चित करें।

+0

धन्यवाद - यह इसे लगभग 60% तक लाया ... – jwoolard

+0

यह कोड मेरे लिए काम करता है। लेकिन नई स्ट्रिंग (बाइटएरे) ने मेरे एंड्रॉइड ऐप को क्रैश कर दिया। क्या आप अंतर समझा सकते हैं? –

8

अपने डेटा तथ्य ASCII (अर्थात 7 बिट डेटा) में है, तो आप के बजाय new String(data, "US-ASCII") का उपयोग कर मंच डिफ़ॉल्ट एन्कोडिंग के आधार पर किया जाना चाहिए। यह आपके प्लेटफ़ॉर्म डिफ़ॉल्ट एन्कोडिंग (जो यूटीएफ -8 हो सकता है, के लिए अधिक आत्मनिरीक्षण की आवश्यकता है) के रूप में इसे समझने की कोशिश करने से तेज़ हो सकता है।

आप Charset उदाहरण कैश करके और new String(data, charset) को कॉल करके प्रत्येक बार वर्णसेट-लुकअप हिट से बचकर इसे तेज कर सकते हैं।

कहा करने के बाद कि: यह एक बहुत, बहुत लंबे समय के बाद से मैं उत्पादन वातावरण

+0

इस और फिनन के उत्तर के बीच क्या अंतर है? – Zyoo

+2

इस बात पर निर्भर करता है कि आप किस उत्पादन वातावरण में हैं, महोदय। मैं हर दिन इसे देखता हूं। – RW4

1

आधी प्रदर्शन में असली ASCII डेटा देखा है हो गया है? इस बाइट सरणी कितनी बड़ी है? यदि यह उदाहरण के लिए 1 एमबी है, तो निश्चित रूप से बाइट्स से वर्णों तक "कनवर्टिंग" की तुलना में ध्यान में रखना अधिक कारक हैं (जो कि हालांकि पर्याप्त तेज़ होना चाहिए)।लेखन "बस" 100bytes के बजाय 1 एमबी डेटा (जो byte[].toString() उत्पन्न हो सकता है) लॉग फ़ाइल में कुछ समय लग रहा है। डिस्क फ़ाइल सिस्टम रैम मेमोरी जितनी तेज नहीं है।

आपको बाइट सरणी के स्ट्रिंग प्रस्तुति को बदलने की आवश्यकता होगी। शायद कुछ और संवेदनशील जानकारी के साथ, उदा। इसके साथ जुड़े नाम (फ़ाइल नाम?), इसकी लंबाई और इतने पर। आखिरकार, उस बाइट सरणी वास्तव में का प्रतिनिधित्व करता है?

संपादित: मैं "लगभग 30us" अपने प्रश्न में वाक्यांश देखा है के लिए याद नहीं कर सकते, हो सकता है आप इसे में पूछ के बाद संपादित 5 मिनट के भीतर, लेकिन यह वास्तव में microoptimization है और यह निश्चित रूप से कारण नहीं करना चाहिए सामान्य रूप से "आधा प्रदर्शन"। जब तक आप उन्हें प्रति सेकंड दस लाख बार नहीं लिखते (तब भी, आप ऐसा क्यों करना चाहते हैं? क्या आप इस घटना को "लॉगिंग" पर अधिक उपयोग नहीं कर रहे हैं?)।

+0

ये सरणी लगभग 150 बाइट्स से 4000 बाइट तक सभी तरह से भिन्न होती हैं। फिर से। आपका आखिरी बिंदु, मैं थ्रूपुट की बजाय विलंबता के लिए अनुकूलित कर रहा हूं - इसलिए मुझे या तो इस रूपांतरण को महत्वपूर्ण पथ से दूर ले जाने की आवश्यकता है, या इसे गति दें ... – jwoolard

+0

इसके अलावा, इस डेटा को लॉग इन करने की आवश्यकता है - और हां , यह बहुत कम डेटा है ... – jwoolard

+0

फिर जावा कोड की तुलना में डिस्क आईओ में आपकी बाधा अधिक है - मुझे उम्मीद है। – BalusC

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^