2012-06-25 15 views
10

मैं सभी शून्य बाइट्स (सभी 0x00) होने के लिए ByteBuffer को "साफ" करने की कोशिश कर रहा हूं। मैंने बफर में सभी पदों पर लूप करने की कोशिश की और उन्हें 0x00 पर सेट किया, लेकिन दक्षता खराब है। ByteBuffer को तुरंत साफ़ करने का कोई बेहतर तरीका है - BitSet.clear() क्या करता है?जावा में बाइटबफर का फास्ट मिट (स्पष्ट नहीं)

कृपया ध्यान दें कि ByteBuffer.clear() इस परिदृश्य में मेरे लिए एक उचित समाधान नहीं है - मुझे बफर के अंदर सभी डेटा मिटाना है, और शुरुआत में पॉइंटर को रीसेट नहीं करना है।

कोई संकेत?

संपादित करें: बाइटबफर का उपयोग हैश तालिका के हिस्से के रूप में किया जाता है, और यह हैश तालिका प्रविष्टियों के संदर्भों को बनाए रखता है। हर बार जब हैश टेबल को फ़्लश करने की आवश्यकता होती है, तो मुझे हैश टेबल प्रविष्टियों को बाद में हैश टेबल प्रविष्टि के लिए रीसेट करना होगा। चूंकि हैश टेबल को यादृच्छिक-फैशन में एक्सेस किया गया है, इसलिए मैं बाइट बफर की स्थिति को साफ़ नहीं कर सकता()।

+0

क्या आप कुछ और विवरण में उपयोग केस की व्याख्या कर सकते हैं? आप बाइटबफर से क्या प्राप्त करते हैं? – jontro

+0

आपको क्यों लगता है कि आपको बफर को शून्य करने की आवश्यकता है? – EJP

+0

क्या यह सीधा बफर है? यदि नहीं, तो बस 'ByteBuffer.wrap (नया बाइट [123456]) के बारे में क्या; ' –

उत्तर

6

क्या आपने एक बार में एकाधिक शून्य लिखने के लिए ByteBuffer.put(byte[]) या ByteBuffer.put(ByteBuffer) विधियों का उपयोग करने का प्रयास किया है? इसके बाद आप 100 या 1000 बाइट्स के हिस्सों में बफर पर फिर से या फिर जो भी सरणी या बफर का उपयोग शून्य से भरे हुए हो सकते हैं।

नकारात्मक पक्ष: यह एक वैकल्पिक आपरेशन है, इसलिए नहीं ByteBuffer के सभी कार्यान्वयन यह प्रदान करने के लिए आवश्यक हैं ...

+0

इसे आज़माएगा। उम्मीद है कि लूप की तुलना में एक थोक डाल बेहतर होगा ... thx! – asksw0rder

+2

इस देर के उत्तर के लिए खेद है, लेकिन यह दृष्टिकोण वास्तव में फ्लशिंग ओवरहेड को कम करने पर काम करता है। मैंने देखा है कि फ्लशिंग समय ~ 60ms से ~ 2ms तक घट गया है। देखेंगे कि यह काफी अच्छा है या नहीं। – asksw0rder

4

ByteBuffer कार्यान्वयन कि वैकल्पिक array() विधि (जहां hasArray() रिटर्न true), तो आप इस इस्तेमाल कर सकते हैं प्रदान के लिए विधि अंतर्निहित सरणी का संदर्भ प्राप्त करें, फिर java.util.Arrays#fill() का उपयोग करें।

1

यदि हैश टेबल फ़्लश होने के बाद आपको ताजा साफ शून्य से भरे बाइटबफर की आवश्यकता है, तो मौजूदा बाइटबुफ्रफ़ को भूलना और एक नया आवंटित करना सबसे आसान तरीका है। आधिकारिक दस्तावेज ऐसा नहीं कहता है, लेकिन सभी ज्ञात कार्यान्वयन नए बफर की स्मृति शून्य है। अतिरिक्त जानकारी के लिए http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6535542 देखें।

1

जैसा कि डीएनए का उल्लेख है, प्री-भरे बफर होने और ByteBuffer.put(ByteBuffer) का उपयोग करना शायद सबसे तेज़ पोर्टेबल तरीका है।

public static void fill(ByteBuffer buf, byte b) { 
    if (buf.hasArray()) { 
     final int offset = buf.arrayOffset(); 
     Arrays.fill(buf.array(), offset + buf.position(), offset + buf.limit(), b); 
     buf.position(buf.limit()); 
    } else { 
     int remaining = buf.remaining(); 
     if (UNALIGNED_ACCESS) { 
      final int i = (b << 24) | (b << 16) | (b << 8) | b; 
      final long l = ((long) i << 32) | i; 
      while (remaining >= 8) { 
       buf.putLong(l); 
       remaining -= 8; 
      } 
     } 
     while (remaining-- > 0) { 
      buf.put(b); 
     } 
    } 
} 

स्थापना UNALIGNED_ACCESS अपने JRE कार्यान्वयन और मंच के कुछ ज्ञान की आवश्यकता है: यदि यह व्यावहारिक नहीं है, आप या तो Arrays.fill या Unsafe.putLong का लाभ लेने के जब लागू कुछ इस तरह कर सकते हैं। यहां बताया गया है कि जब मैं जेएनए का उपयोग करता हूं तो मैं ओरेकल जेआरई के लिए इसे कैसे सेट करूंगा (जो Platform.ARCH को os.arch सिस्टम प्रॉपर्टी तक पहुंचने के लिए सुविधाजनक, कैननिकल तरीके के रूप में प्रदान करता है)।

/** 
* Indicates whether the ByteBuffer implementation likely supports unaligned 
* access of multi-byte values on the current platform. 
*/ 
private static final boolean UNALIGNED_ACCESS = Platform.ARCH.startsWith("x86"); 
संबंधित मुद्दे