2012-03-09 18 views
16

मेरे पास एक ऐसा एप्लिकेशन है जिसमें प्रदर्शन कारणों के लिए मेमोरी में ~ 1,000,000 तार हैं। मेरा आवेदन ~ 200 एमबी रैम खपत करता है।.NET स्ट्रिंग गहन अनुप्रयोगों पर मेमोरी पदचिह्न को कैसे कम करें?

मैं तारों से खपत स्मृति की मात्रा को कम करना चाहता हूं।

मुझे पता है .NET यूटीएफ -16 एन्कोडिंग (2 बाइट प्रति चार) में स्ट्रिंग का प्रतिनिधित्व करता है। मेरे आवेदन में अधिकांश तारों में शुद्ध अंग्रेजी वर्ण होते हैं, इसलिए उन्हें यूटीएफ -8 एन्कोडिंग में संग्रहीत करना यूटीएफ -16 की तुलना में 2 गुना अधिक कुशल होगा।

मानक स्ट्रिंग फ़ंक्शंस की अनुमति देते हुए यूटीएफ -8 एन्कोडिंग में स्मृति में स्ट्रिंग को स्टोर करने का कोई तरीका है? (StringComparison.OrdinalIgnoreCase के साथ ज्यादातर इंडेक्सऑफ सहित मेरी ज़रूरतें)।

+0

बाइट सरणी या 'सूची ' का उपयोग करने के बारे में क्या? यह सुनिश्चित नहीं है कि आपकी जरूरतों के लिए इन वस्तुओं के साथ काम करना कितना मुश्किल होगा। –

+0

@ डीएक्सकेक, आप "चाहते हैं" या "ज़रूरत"? दिलचस्प जवाब या व्यावहारिक प्रदान करने के लिए अंतर महत्वपूर्ण है। –

+3

क्या आपको पूरी तरह से सभी 1,000,000 तारों को स्मृति में लोड करना है? क्या आप स्मृति में इन सभी तारों के साथ वास्तव में क्या कर रहे हैं, इस बारे में अधिक जानकारी प्रदान कर सकते हैं? –

उत्तर

0

क्या होगा यदि आप अपनी खुद की यूटीएफ -8 स्ट्रिंग क्लास (यूटीएफ 8 स्ट्रिंग?) बनाते हैं और स्ट्रिंग को एक निहित कास्ट प्रदान करते हैं? आप स्मृति के लिए कुछ गति बलिदान करेंगे, लेकिन यह हो सकता है कि आप जो खोज रहे हैं।

+0

मैंने कोशिश की। स्ट्रिंग में वापस कनवर्ट करना शायद ही कभी प्रदर्शन लागत है। यूटीएफ -8 से यूटीएफ -16 में परिवर्तित, फिर जीसी इसे। 1,000,000 स्ट्रिंग के लिए यह बहुत ही ध्यान देने योग्य लागत है। – DxCK

2

क्या होगा यदि आप इसे एक बाइटियर के रूप में स्टोर करते हैं? जब आपको उस पर कुछ संचालन करने की आवश्यकता होती है तो बस स्ट्रिंग पर पुनर्स्थापित करें। मैं & को तारों को प्राप्त करने के लिए एक कक्षा बनाउंगा जो आंतरिक रूप से इसे बाइटियर के रूप में बंद कर देता है।

bytearray रहे हैं:

string s = "whatever"; 
byte[] b = System.Text.Encoding.UTF8.GetBytes(s); 

स्ट्रिंग के लिए:

string s = System.Text.Encoding.UTF8.GetString(b); 
+1

मैंने कोशिश की। स्ट्रिंग में वापस कनवर्ट करना मुश्किल प्रदर्शन लागत है: स्मृति आवंटित करना, यूटीएफ -8 से यूटीएफ -16 में परिवर्तित करना, फिर जीसी इसे परिवर्तित करना। 1,000,000 स्ट्रिंग के लिए यह बहुत ही ध्यान देने योग्य लागत है। – DxCK

+0

@ डीएक्सकेक "फिर जीसी यह" - इसका मतलब क्या है? –

+0

अच्छी तरह से आप क्या चाहते हैं ... प्रदर्शन या एक छोटे पदचिह्न? :) क्या आपके ऐप को लगातार प्रत्येक स्ट्रिंग की आवश्यकता है? यदि संभवतः केवल तारों को स्टोर न करें जो थोड़ी देर में उपयोग नहीं किए गए हैं। एक वर्ग बनाएं जो कचरा इकट्ठा करने के बजाय किसी प्रकार की आंतरिक 'स्मृति संग्रह' करता है। – SpoBo

4

वहाँ मानक स्ट्रिंग> कार्यों की अनुमति UTF-8 एन्कोडिंग में स्मृति में एक स्ट्रिंग स्टोर करने के लिए एक तरीका है? (StringComparison.OrdinalIgnoreCase के साथ ज्यादातर इंडेक्सऑफ सहित मेरी ज़रूरतें)।

आप एक बाइट सरणी के रूप में संग्रहीत कर सकती है, और (indexOf के लिए स्ट्रिंग के लिए वापस परिवर्तित होने की संभावना एक विशाल प्रदर्शन हिट गाना बन गया के बाद से) अपनी खुद की indexOf कार्यान्वयन प्रदान करते हैं। उस के लिए System.Text.Encoding फ़ंक्शंस का उपयोग करें (सर्वोत्तम शर्त बाइट में कनवर्ट करने के लिए एक बिल्ड चरण करना होगा, और उसके बाद डिस्क से बाइट सरणी पढ़ें - यदि आवश्यक हो तो केवल प्रदर्शन के लिए स्ट्रिंग में कनवर्ट करना)।

आप उन्हें एक सी/सी ++ लाइब्रेरी में स्टोर कर सकते हैं, जिससे आप एकल बाइट स्ट्रिंग का उपयोग कर सकते हैं। आप शायद उन्हें वापस मार्शल नहीं करना चाहते हैं, लेकिन संभवतः आप केवल मार्शल परिणाम (मुझे लगता है कि यहां कुछ प्रकार की खोज चल रही है) बिना किसी पेफ हिट के। सी ++/सीएलआई इसे आसान बना सकता है (सी ++/सीएलआई में खोज कोड लिखने में सक्षम होने के कारण, लेकिन सी ++ में स्ट्रिंग "डेटाबेस")।

या, आप अपने प्रारंभिक प्रदर्शन मुद्दों पर फिर से जा सकते हैं जिन्हें स्मृति में सभी तारों की आवश्यकता होती है। एक एम्बेडेड डेटाबेस, इंडेक्सिंग इत्यादि दोनों और मेमोरी उपयोग को कम कर सकते हैं - और अधिक रखरखाव योग्य हो सकते हैं।

+0

कोई इग्निरेकेज़ वर्णों की तुलना कैसे कार्यान्वित कर सकता है? क्या सी/सी ++ में कोई यूटीएफ -8 पुस्तकालय/प्रतिनिधित्व उपलब्ध है? – DxCK

+0

@DxCK आपके पास समस्या है यदि आप 8 बिट्स तक सीमित हैं, तो आप दुनिया में इस्तेमाल होने वाली भाषाओं के एक बड़े हिस्से का समर्थन नहीं करते हैं, यहां तक ​​कि सी ++ और यूटीएफ 8 –

+1

@Chris S UTF8 एन्कोडिंग भाषा को कैसे सीमित करता है? – DxCK

11

दुर्भाग्यवश, आप स्ट्रिंग का .NET आंतरिक प्रतिनिधित्व नहीं बदल सकते हैं। मेरा अनुमान है कि सीएलआर मल्टीबाइट तारों के लिए अनुकूलित है।

क्या आप के साथ काम कर रहे हैं Space-time tradeoff के प्रसिद्ध प्रतिमान, जिसमें कहा गया है कि आदेश स्मृति हासिल करने के आप अधिक प्रोसेसर का उपयोग करना होगा या आप कुछ स्मृति का उपयोग करके प्रोसेसर बचा सकता है।

उस ने कहा, here पर कुछ विचारों पर नज़र डालें।अगर मैं आप थे, एक बार स्थापित किया गया कि स्मृति लाभ आपके लिए पर्याप्त होगा, तो अपनी खुद की "स्ट्रिंग" कक्षा लिखने का प्रयास करें, जो ASCII एन्कोडिंग का उपयोग करता है। यह शायद पर्याप्त होगा।

अद्यतन:

पैसे पर

अधिक, आप इस पोस्ट की जाँच करनी चाहिए, "Of memory and strings", StackOverflow कथा जॉन स्कीट जो समस्या आप का सामना कर रहे के साथ संबंधित है। खेद है कि मैंने तुरंत इसका उल्लेख नहीं किया, मुझे जॉन से सटीक पोस्ट खोजने में कुछ समय लगा।

2

डेटा के साथ बातचीत करने के लिए "स्टोरेज" और एसक्यूएल के रूप में एक इन-मेमोरी-डीबी का उपयोग करने का प्रयास करें ... उदाहरण के लिए SQLite को आपके एप्लिकेशन के हिस्से के रूप में तैनात किया जा सकता है (केवल 1-2 डीएलएल होते हैं जिन्हें रखा जा सकता है आपके आवेदन के समान फ़ोल्डर में) ...