2016-04-28 5 views
5

मैं वर्तमान में doing more stuff with arrays देख रहा हूं, लेकिन मुझे लगता है कि अगर हम किसी भी तरह से Leaked<T> में आगे बढ़ने की इजाजत देते हैं, तो फ़ंक्शन समाप्त होने पर इसे अन-रिसाव करने के लिए उन परिचालनों का प्रदर्शन बेहतर हो सकता है। यह हमें बिना किसी सुरक्षा के लीक एम्पलीफिकेशन का उपयोग करने देगा) बी catch_panic(_) स्थापित करना। क्या यह जंग में किसी भी तरह से संभव है?क्या कोई मूल्य पूर्व-अन-लीक करने का कोई तरीका है?

उदाहरण के लिए

, एक पुनरावर्तक से एक सामान्य सरणी (इस स्पष्ट रूप से काम नहीं करता है) बनाने:

#[inline] 
fn map_inner<I, S, F, T, N>(list: I, f: F) -> GenericArray<T, N> 
where I: IntoIterator<Item=S>, F: Fn(&S) -> T, N: ArrayLength<T> { 
    unsafe { 
     // pre-leak the whole array, it's uninitialized anyway 
     let mut res : GenericArray<Leaked<T>, N> = std::mem::uninitialized(); 
     let i = list.into_iter(); 
     for r in res.iter_mut() { 
      // this could panic anytime 
      std::ptr::write(r, Leaked::new(f(i.next().unwrap()))) 
     } 
     // transmuting un-leaks the array 
     std::mem::transmute::<GenericArray<Leaked<T>, N>, 
           GenericArray<T, N>>(res) 
    } 
} 

मैं नोट करना चाहिए कि हम या तो T के आकार या एक प्रकार के संकलन समय पहुंच प्राप्त हो कि उधार से अपने अंदरूनी छिपा सकते हैं (जैसे उदाहरण में Leaked<T>), यह पूरी तरह से व्यवहार्य है।

+0

आप जिस प्रदर्शन की उम्मीद कर रहे हैं उसमें सुधार प्रदर्शन क्या हैं? 'लेन 'बढ़ाना नहीं है? – malbarbo

+0

यदि मैं पैनिक्स को पकड़कर लीकिंग को रोकने की कोशिश करता हूं (जो अभी भी बीटा/रात में काम करता है), मुझे 'वीईसी' में एकत्र करने से लगभग 45% अधिक थ्रूपुट मिलता है। मुझे लगता है कि मैं प्री-लीकिंग से भी बेहतर परिणाम प्राप्त कर सकता हूं। – llogiq

उत्तर

3

nodrop का उपयोग करना संभव है, लेकिन यह रिसाव हो सकता है।

fn map_inner<I, S, F, T, N>(list: I, f: F) -> GenericArray<T, N> 
where I: IntoIterator<Item=S>, F: Fn(&S) -> T, N: ArrayLength<T> { 
    unsafe { 
     // pre-leak the whole array, it's uninitialized anyway 
     let mut res : NoDrop<GenericArray<T, N>> = NoDrop::new(std::mem::uninitialized()); 
     let i = list.into_iter(); 
     for r in res.iter_mut() { 
      // this could panic anytime 
      std::ptr::write(r, f(i.next().unwrap())) 
     } 
     res.into_inner() 
    } 
} 

चलो लगता है कि पहले आइटम (a) के बाद i से भस्म और r को लिखा है, एक आतंक होता है। i से शेष आइटम ड्रॉप हो जाएंगे, लेकिन आइटम a नहीं होगा। हालांकि स्मृति is not लीकिंग असुरक्षित माना जाता है, यह वांछनीय नहीं है।

मुझे लगता है कि प्रश्न लिंक में वर्णित दृष्टिकोण जाने का तरीका है। यह Vec और ArrayVec कार्यान्वयन के समान है। मैं सरणी पुस्तकालय में एक समान दृष्टिकोण का उपयोग कर रहा हूं जिसे मैं लिख रहा हूं।

+0

धन्यवाद! यह वहीं है जिसे मैं ढूंढ रहा था। – llogiq

+1

@llogiq यदि आप रुचि रखते हैं, तो मैंने दूसरे प्रश्न का उत्तर देने के लिए कुछ कोड लिखा है जो इस तरह के निर्माण को रिसाव नहीं करता है। Http://stackoverflow.com/questions/36925673/how-can-i-initialize-an-array-using-a-function – malbarbo

+0

फिर से धन्यवाद - यह अधिकतर है जो मैं आया था उसके बराबर है। मेरे मानक बहुत ही आशाजनक हैं, बहुत सादे सरणी निर्माण के बहुत पास हैं। – llogiq

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