2012-01-16 15 views
5

मेरे पास एक सी # एप्लिकेशन है जिसे प्रति सेकंड कई हजार प्रोटोबफ संदेशों को बेकार करने की आवश्यकता है। अनावश्यक कचरा संग्रह से बचने के हित में, मैं सोच रहा हूं कि प्री-आवंटित स्मृति का उपयोग करने का कोई तरीका है ताकि प्रत्येक deserialization ऑपरेशन को नई स्मृति आवंटित करने की आवश्यकता नहीं होगी।प्रोटोबफ-नेट का उपयोग करना, स्मृति को आवंटित किए बिना संदेश को deserialize करना संभव है?

मुझे क्या लगता है कि मैं निष्पादन से पहले संदेश वस्तुओं का एक पूल आवंटित करूंगा, और फिर प्रत्येक deserialization के लिए इस पूल से अगले उपलब्ध संदेश का उपयोग करने के लिए protobuf कोड निर्देश।

क्या यह कार्यक्षमता मौजूद है, या इस परिदृश्य में स्मृति उपयोग को अनुकूलित करने के लिए कोई अन्य तरीका है?

धन्यवाद!

+2

क्या आपने यह निर्धारित किया है कि यह वास्तव में समस्या है? क्या आपने इस परिदृश्य में भाग लिया है जहां आप ऐप मेमोरी पर कम चल रहे हैं या कचरा संग्रह के कारण धीमी गति से चल रहे हैं? – BFree

+0

नहीं, लेकिन यह उच्च आवृत्ति घटक में कोड का एकमात्र क्षेत्र है जिसे वर्तमान में स्मृति आवंटित करने की आवश्यकता है, इसलिए इसे समाप्त करने की संभावना का पता लगाने के लिए मेरे लिए उपयुक्त लगता है, खासकर यदि ऐसा करने के लिए एक सीधा दृष्टिकोण है। – newdayrising

+0

वस्तुओं की आवंटन और कचरा संग्रह जो अल्पकालिक हैं, बेहद तेज़ हैं।आपको शायद इस बारे में चिंता न करें जबतक कि आप वास्तव में अपना कोड प्रोफ़ाइल न करें और पता लगाएं कि यह बाधा है। – svick

उत्तर

10

हाँ, वहाँ है! आंतरिक रूप से, यह पहले से ही बहुत से काम कर रहे बफर आवंटित करने से बचने के लिए माइक्रो-पूल का उपयोग करता है, लेकिन यदि आप पर्याप्त वस्तुएं डाल रहे हैं कि जीसी एक मुद्दा है, तो आप शायद अपनी आवंटन योजना का उपयोग कर सकते हैं और एक कस्टम ऑब्जेक्ट फैक्ट्री बना सकते हैं; इस विशेषताओं वर्तमान में निर्दिष्ट नहीं किया जा सकता है, लेकिन टाइप मॉडल के माध्यम से लागू किया जा सकता:

RuntimeTypeModel.Default.Add(typeof (Foo), true).SetFactory(factory); 

जहां factory है या तो:

  • नाम Foo पर एक static विधि के (यानी "CreateFoo") जो Foo
  • MethodInfo किसी भी static विधि (को करने की आवश्यकता नहीं है) की आवश्यकता नहीं है Foo पर हो) कि या तो मामले में रिटर्न एक Foo

, विधि कॉलबैक के रूप में एक ही हस्ताक्षर का उपयोग कर सकते हैं - तो यह parameterless हो सकता है, या संदर्भ जानकारी को स्वीकार कर सकते हैं। उदाहरण के लिए:

public static Foo CreateFoo() { 
    return GetFromYourOwnMicroPool(); 
} 

नोट इस प्रयोग में, यह उम्मीद है कि कि कारखाने एक वेनिला राज्य के लिए वस्तु रीसेट कर देगा; protobuf- नेट ऐसा करने का प्रयास नहीं करेगा। ध्यान दें कि वर्तमान में प्रोटोबफ-नेट इसका पुन: प्रयोज्य घटक के रूप में माइक्रो-पूल का पर्दाफाश नहीं करता है, लेकिन आप आसानी से स्रोत का पुनः उपयोग कर सकते हैं।

यह कार्यक्षमता विशेष रूप से बहुत ही उच्च throughput जो भी थोड़ी सी जी सी ओवरहेड्स को दूर करना चाहता था के साथ एक उपयोगकर्ता का समर्थन करने के लिए जोड़ा गया था (मापन के बहुत सारे के आधार पर ... वे मेरे बहुत रेखांकन और सब कुछ भेजा, पी)

इसके अतिरिक्त : रूट ऑब्जेक्ट के अपवाद के साथ, प्रोटोबफ-नेट struct बिना मुक्केबाजी के मूल्यों का समर्थन करता है; इसलिए यदि आपके पास जटिल/नेस्टेड ऑब्जेक्ट मॉडल है, तो चरम मामलों में एक और विकल्पstruct एस को देखना है।

+0

क्या आप कृपया स्पष्ट कर सकते हैं कि structs का उपयोग कैसे करें? क्या हम प्रोटोटा फ़ाइल से उत्पन्न करते समय ऐसा कर सकते हैं? जिथूब रीडेमे पर इस कथन के बारे में क्या? 'कोड मानता है कि निर्वाचित सदस्यों के आसपास प्रकार बदल सकते हैं। तदनुसार, कस्टम structs समर्थित नहीं हैं, क्योंकि वे अपरिवर्तनीय होना चाहिए। – Aranda

+0

@ अरंदा कि टिप्पणी structs के लिए समर्थन पूर्व निर्धारित कर सकते हैं। पीढ़ी का उपकरण केवल इस समय कक्षाओं को उत्सर्जित करता है, लेकिन structs को ठीक काम करना चाहिए। –

+0

धन्यवाद मार्क। मैंने इसे जेनरेट किए गए वर्गों को मैन्युअल रूप से संपादित करने के लिए काम किया है (गैर-रूट प्रकारों के लिए), लेकिन सभी आवंटन को खत्म नहीं कर सका क्योंकि कारखाने के दृष्टिकोण और विलय दृष्टिकोण दोनों रूट प्रकारों के आवंटन को खत्म नहीं कर पाए। हम अभी के लिए Flatbuffers में एक स्विच का परीक्षण कर रहे हैं। – Aranda

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

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