2011-09-08 10 views
10

मैं एक विंडोज फोन 7 एक्सएनए गेम पर काम कर रहा हूं। यह सी ++ में लिखे गए गेम का एक बंदरगाह है, और इस तरह, मैं जितना संभव हो गेमप्ले कोड के छोटे पुनर्लेखन के रूप में करने की कोशिश कर रहा हूं। क्योंकि कलेक्टर nongenerational और धीमी गति से है, इसलिए एक संग्रह (जो प्रत्येक 1 MB शुरू हो रहा है) 10ms के बारे में आवंटन के प्रति MB लेताWP7 सी #/XNA में उत्परिवर्तनीय तार?

कचरा, एक विशाल WP7 पर समस्या है। मैं पूरी तरह से अधिकतम 9 0 एमबी उपलब्ध कराने का इरादा रखता हूं, इसलिए हम आवंटन के प्रत्येक एमबी में ~ 900 एमएमएस स्टॉल देख रहे हैं।

मैं चीजों को फिर से काम करने में सक्षम हूं ताकि हमारे पास स्ट्रिंग के कुछ मामलों को छोड़कर प्रति फ्रेम उत्पन्न कचरा न हो।

ऐसा लगता है कि स्ट्रिंगबिल्डर। टॉस्ट्रिंग() कचरा उत्पन्न करता है, और here वर्णित विधि WP7 पर काम नहीं करती है।

दो बातें मैं क्या करने की जरूरत हैं:

  • स्वरूप मिनट/सेकंड/मिमी के रूप में hundreths: स्क्रीन पर प्रदर्शित करने के लिए ss.hh। जाहिर है, मैं स्ट्रिंगबिल्डर के साथ ऐसा कर सकता हूं (एक्सटेंशन विधियों का उपयोग करना जो मुक्केबाजी से कचरे से कचरा नहीं बनाते हैं) और स्ट्रिंगबिल्डर को सीधे स्प्राइटबैच के साथ प्रदर्शित करते हैं।
  • 'foo.bar.baz.qux "फ़ॉर्म की एक स्ट्रिंग को'। ', यानी {" foo "," bar "," baz "," qux "} पर एक सरणी में विभाजित करें और एक तत्व को कॉपी करें तारों की एक सरणी में समय। यह गेम अभिनेताओं की पदानुक्रमिक स्थिति स्थापित करने के लिए है। यह मूल गेम से सीधे बहुत अधिक पोर्ट किया गया है, और इस तरह से काम करने पर काफी निर्भर करता है। मैं वास्तव में इसे फिर से लिखना टालना चाहूंगा।

स्ट्रिंग के बजाय char [] का उपयोग करने के लिए बहुत सारे कोड को कनवर्ट करने का छोटा, क्या सी # में वास्तव में कचरा मुक्त म्यूटेबल तारों का कोई तरीका है?

+2

बस एक साइड नोट आम में पीढ़ी जीसी है http://blogs.msdn.com/b/abhinaba/archive/2011/04/13/generational-gc-in-windows-phone-mango.aspx – Terrance

+0

यह भी है mutable तारों के लिए कुछ "करीब" बनाने का एक तरीका http://stackoverflow.com/questions/6913435/how-to-get-a-list-of-mutable-strings – Terrance

उत्तर

10

आपको StringBuilder को पहले स्थान पर String में बदलने की आवश्यकता क्यों है? जैसा कि आपने नोट किया है, आप StringBuilder सीधे XNA के ड्राइंग विधियों में पास कर सकते हैं। तुम भी सबस्ट्रिंग पुनः प्राप्त करने के StringBuilder उपयोग कर सकते हैं:

substringBuilder.Length = 0; 
for (int i = start; i <= end; i++) 
    substringBuilder.Append(originalBuilder[i]); 

केवल बातें आप StringBuilder ToString() और AppendFormat() हैं साथ बचना चाहते हैं। अन्य स्वरूपण विधियों में से कोई भी (मेरे ज्ञान के लिए) कचरा उत्पन्न नहीं करता है। अपडेट: मैं गलत था। अपनी खुद की विस्तार विधियां लिखें। यहां एक रैंड डाउन उपलब्ध है: Avoiding garbage when working with StringBuilder

यह एक विधि लिखना अपेक्षाकृत आसान है जो किसी दिए गए डिलीमीटर के आधार पर एक स्ट्रिंग को सबस्ट्रिंग में विभाजित करेगा। बस याद रखें कि String.Split()दो कारणों के लिए बुरा है - पहला, क्योंकि यह नए तार आवंटित करता है; और दूसरा, क्योंकि यह एक नया सरणी आवंटित करता है। तारों की अपरिवर्तनीयता आपकी समस्या का केवल आधा है।

StringBuilder के लिए निम्न एक्सटेंशन विधियों पर विचार करें। मैंने इस कोड का पूरी तरह से परीक्षण नहीं किया है, लेकिन यह आपको एक सामान्य विचार देना चाहिए। ध्यान दें कि यह आपको पूर्व-आवंटित सरणी में गुजरने की अपेक्षा करता है, जिसे वह तब पॉप्युलेट करेगा।

public static void Substring(this StringBuilder source, Int32 start, Int32 count, StringBuilder output) 
{ 
    output.Length = 0; 
    for (int i = start; i < start + count; i++) 
    { 
     output.Append(source[i]); 
    } 
} 

public static int Split(this StringBuilder source, Char delimiter, StringBuilder[] output) 
{ 
    var substringCount = 0; 
    var substringStart = 0; 
    for (int i = 0; i < source.Length; i++) 
    { 
     if (source[i] == delimiter) 
     { 
      source.Substring(substringStart, i - substringStart, output[substringCount]); 
      substringCount++; 
      substringStart = i + 1; 
     } 
    } 
    if (substringStart < source.Length - 1) 
    { 
     source.Substring(substringStart, source.Length - substringStart, output[substringCount]); 
     substringCount++; 
    } 
    return substringCount; 
} 
+1

गैर-स्ट्रिंग ऑब्जेक्ट्स स्वरूपण (उदाहरण: संख्याएं) कचरा उत्पन्न करें (यह उनकी 'ToString' विधि को कॉल करता है)। लेकिन पूर्णांक (या अधिकतर अन्य प्रकार, वास्तव में) को जोड़ने के लिए कचरा मुक्त एक्सटेंशन विधि लिखना बहुत मुश्किल है। आप ऑनलाइन आसानी से उदाहरण पा सकते हैं। –

+0

डिकंपील्ड स्रोत के माध्यम से एक त्वरित रूप से पुष्टि करता है कि आप सही हैं। मुझे यकीन नहीं है कि मैंने अन्यथा क्यों सोचा। लेकिन हाँ, आप इसके आसपास काम कर सकते हैं। –

0

मैं संभव के रूप में गेमप्ले कोड के रूप में छोटे नए सिरे से लिखना करने के लिए कोशिश कर रहा हूँ।

इसके साथ सावधान रहें कि इसे फिर से लिखना अधिक समय लगेगा। कोल कैंपबेल सही है, जब आप इसे आकर्षित करना चाहते हैं तो ToString() को कॉल करने में कोई बात नहीं है। एक्सएनए में ड्रॉ विधि है जो स्ट्रिंगबुलियर लेती है और यह मेरे गेम में अच्छी तरह से काम करती है।

आपकी समस्या का एक और समाधान: अपने तारों का वैश्विक हैशसेट बनाएं और जब आप संग्रह दबाव से बचने के लिए गेम या स्तर लोड करते हैं तो इसे स्थापित करें।

जब आप खेल लोड करते हैं तो जितना संभव हो उतना करने का प्रयास करें।