दिलचस्प पोस्ट
आप एक सीएसएस चयनकर्ता में वंश का समूह क्यों नहीं कर सकते? एक संशोधित प्रीर्डर ट्री ट्रवर्सल मॉडल (नेस्टेड सेट) को एक <ul> में लेना सूची में सबसे लंबी स्ट्रिंग चुनने के लिए पायथन का सबसे कारगर तरीका है? मैं गतिशील रूप से एक जावा सरणी में आइटम कैसे जोड़ सकता हूं? स्काइप एपीआई का कार्यान्वयन आवेदन में अंतर / जेसन और आवेदन / एक्स-www-फॉर्म-यूआरएलएक्सोडेड किसी भी तरह से स्मृति में कर्ल की कुकीज़ रखने के लिए और डिस्क पर नहीं जावास्क्रिप्ट वस्तु Vs JSON DeploymentItem विशेषता के साथ समस्याएं ओरेकल में कई पंक्तियों में विभाजन स्ट्रिंग एंड्रॉइड पर वेबकिट के लिए क्या डोम इवेंट्स उपलब्ध हैं? सीखने आईफोन गेम विकास TypeError: 'इंट ऑब्जेक्ट' को ट्रांज़िट में परिवर्तित नहीं किया जा सकता SCRIPT438: ऑब्जेक्ट संपत्ति या विधि IE का समर्थन नहीं करता PHP mysql_real_escape_string () -> स्ट्रिप्सस्ैश () एकाधिक स्लैश छोड़कर

मेमोरी क्षमता और स्ट्रिंग के प्रदर्शन। रीप्लस। नेट फ्रेमवर्क

string str1 = "12345ABC...\\...ABC100000"; // Hypothetically huge string of 100000 + Unicode Chars str1 = str1.Replace("1", string.Empty); str1 = str1.Replace("22", string.Empty); str1 = str1.Replace("656", string.Empty); str1 = str1.Replace("77ABC", string.Empty); // ... this replace anti-pattern might happen with upto 50 consecutive lines of code. str1 = str1.Replace("ABCDEFGHIJD", string.Empty); 

मैं कुछ कोड विरासत में मिला है जो ऊपर स्निपेट के समान है I यह एक बड़ी स्ट्रिंग लेता है और बड़ी स्ट्रिंग से लगातार छोटे स्ट्रिंग को बदल देता है (हटाता है)।

मेरा मानना ​​है कि यह एक बहुत ही स्मृति गहन प्रक्रिया है कि नए बड़े अपरिवर्तनीय स्ट्रिंग को प्रत्येक प्रतिस्थापन के लिए स्मृति में आवंटित किया जा रहा है, जीसी के माध्यम से मौत का इंतजार कर रहा है।

1. स्मृति चिंताओं को अनदेखा करते हुए इन मूल्यों को बदलने का सबसे तेज़ तरीका क्या है?

2. एक ही परिणाम प्राप्त करने का सबसे स्मृति कुशल तरीका क्या है?

मुझे उम्मीद है कि ये एक ही जवाब हैं!

व्यावहारिक समाधान जो इन लक्ष्यों के बीच में कहीं फिट हैं उन्हें भी सराहना है।

मान्यताओं:

  • सभी प्रतिस्थापन निरंतर और अग्रिम में ज्ञात हैं
  • अंतर्निहित पात्रों में कुछ यूनिकोड [गैर-असीसी] वर्ण होते हैं

Solutions Collecting From Web of "मेमोरी क्षमता और स्ट्रिंग के प्रदर्शन। रीप्लस। नेट फ्रेमवर्क"

.NET स्ट्रिंग में सभी वर्ण "यूनिकोड वर्ण" हैं क्या आपका मतलब है कि वे गैर-आस्की हैं? इससे कोई भी बाधाएं नहीं होनी चाहिए – जब तक आप संरचना मुद्दों में नहीं चलते हैं, उदाहरण के लिए जब आप "ई तीव्र" को बदलने का प्रयास करते हैं तो "ई + तीव्र तीव्रता" को नहीं बदला जा रहा है

आप Regex.Replace साथ एक नियमित अभिव्यक्ति का उपयोग करने की कोशिश कर सकते हैं। Regex.Replace , या StringBuilder.ReplaceStringBuilder.Replace । यहाँ नमूना कोड दोनों के साथ एक ही बात कर रही है:

 using System; using System.Text; using System.Text.RegularExpressions; class Test { static void Main(string[] args) { string original = "abcdefghijkl"; Regex regex = new Regex("a|c|e|g|i|k", RegexOptions.Compiled); string removedByRegex = regex.Replace(original, ""); string removedByStringBuilder = new StringBuilder(original) .Replace("a", "") .Replace("c", "") .Replace("e", "") .Replace("g", "") .Replace("i", "") .Replace("k", "") .ToString(); Console.WriteLine(removedByRegex); Console.WriteLine(removedByStringBuilder); } } 

मुझे लगता है कि जो अधिक कुशल है – आप अपने विशिष्ट अनुप्रयोग के साथ बेंचमार्क करना होगा Regex मार्ग एक पास में यह सब करने में सक्षम हो सकता है, लेकिन यह पास अपेक्षाकृत सीपीयू-सघन होता है, जो स्ट्रिंगबिइल्डर में जगह लेता है।

यदि आप वास्तव में तेजी से रहना चाहते हैं, और मेरा मतलब है कि वास्तव में तेजी से आपको StringBuilder से परे देखना होगा और बस अच्छी तरह से अनुकूलित कोड लिखना होगा।

एक बात जो आपके कंप्यूटर को नहीं करना पसंद है, अगर आप एक निश्चित विधि लिख सकते हैं जो एक निश्चित सरणी (चार *) पर चलती है और शाखा नहीं करता है तो आपके पास बहुत अच्छा प्रदर्शन है

आप जो कर रहे हैं वह है कि प्रतिस्थापन ऑपरेशन वर्णों के अनुक्रम के लिए खोज करने जा रहा है और अगर उसे ऐसा कोई उप स्ट्रिंग लगता है जो इसे बदल देगा। असल में आप स्ट्रिंग की प्रतिलिपि बना लेंगे और ऐसा करते समय, ढूंढें और प्रतिस्थापित करें।

पढ़ने के लिए लिखने के लिए कुछ बफर के सूचक को चुनने के लिए आप इन कार्यों पर भरोसा करेंगे। लक्ष्य को प्रतिस्थापन पद्धति को प्राथमिकता देना है, जैसे कि जब कुछ भी बदलना न हो, तो आप शाखा के बजाय जंक लिखते हैं।

आप इसे एक एकल बयान के बिना पूरा करने में सक्षम होना चाहिए और असुरक्षित कोड का उपयोग करने के लिए याद रखना चाहिए। अन्यथा आप प्रत्येक एलीमेंट एक्सेस के लिए सूचकांक की जांच के लिए भुगतान करेंगे।

 unsafe { fixed( char * p = myStringBuffer ) { // Do fancy string manipulation here } } 

मैंने मजाक के लिए सी # में कोड लिखा है और महत्वपूर्ण प्रदर्शन में सुधार देखा है, लगभग 300% की खोज और प्रतिस्थापित करने के लिए गति जबकि नेट बीसीएल (बेस क्लास लाइब्रेरी) काफी अच्छी तरह से काम करता है, यह शाखाओं के निर्माण के साथ छलती हुई है और अपवाद निपटने से आप कोड को धीमा कर सकते हैं यदि आप अंतर्निर्मित सामान का उपयोग करते हैं इसके अलावा, इन अनुकूलन को पूरी तरह से ध्वनि जेआईटी-संकलक द्वारा नहीं बनाया गया है और आपको बिना किसी डिबगर के बड़े पैमाने पर कार्यक्षमता हासिल करने के लिए कोड को रिहाई के रूप में चलाया जाना चाहिए।

मैं आपको और अधिक पूर्ण कोड प्रदान कर सकता हूं लेकिन यह काम का एक महत्वपूर्ण हिस्सा है। हालांकि, मैं आपको गारंटी दे सकता हूं कि यह अभी तक सुझाए गए चीज़ों की तुलना में तेज़ हो जाएगा।

स्ट्रिंगबिल्डर: http://msdn.microsoft.com/en-us/library/2839d5h5.aspx

प्रतिस्थापन ऑपरेशन के प्रदर्शन को लगभग स्ट्रिंग के समान होना चाहिए। माइक्रोसॉफ्ट के अनुसार और कचरा का उत्पादन नहीं किया जाना चाहिए।

यहां एक त्वरित बेंचमार्क है …

  Stopwatch s = new Stopwatch(); s.Start(); string replace = source; replace = replace.Replace("$TS$", tsValue); replace = replace.Replace("$DOC$", docValue); s.Stop(); Console.WriteLine("String.Replace:\t\t" + s.ElapsedMilliseconds); s.Reset(); s.Start(); StringBuilder sb = new StringBuilder(source); sb = sb.Replace("$TS$", tsValue); sb = sb.Replace("$DOC$", docValue); string output = sb.ToString(); s.Stop(); Console.WriteLine("StringBuilder.Replace:\t\t" + s.ElapsedMilliseconds); 

मुझे मेरी मशीन पर ज्यादा अंतर नहीं देखा गया (स्ट्रिंग.रेस्थे 85ms थी और स्ट्रिंगबिल्ल्डर.रेस्थल 80 थी), और यह "स्रोत" में लगभग 8 एमबी पाठ के खिलाफ था …

1. स्मृति चिंताओं को अनदेखा करते हुए इन मूल्यों को बदलने का सबसे तेज़ तरीका क्या है?

सबसे तेज़ तरीका कस्टम प्रदाता बनाना है जो आपके उपयोग के मामले के लिए विशिष्ट है। .NET 4.6 के अनुसार, एकाधिक स्ट्रिंग प्रतिस्थापन के लिए डिज़ाइन किए गए बीसीएल में कोई वर्ग नहीं है।

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

2. एक ही परिणाम प्राप्त करने का सबसे स्मृति कुशल तरीका क्या है?

सबसे स्मृति कुशल तरीके से स्रोत से गंतव्य तक एक फ़िल्टर की गई स्ट्रीम की प्रतिलिपि (नीचे समझाया गया) करना है स्मृति खपत आपके बफ़र तक सीमित होगी, हालांकि यह अधिक सीपीयू गहन होगा; अंगूठे के नियम के रूप में, आप स्मृति उपभोग के लिए सीपीयू प्रदर्शन को व्यापार करने जा रहे हैं

तकनीकी जानकारी

स्ट्रिंग प्रतिस्थापन मुश्किल हैं यहां तक ​​कि जब एक अस्थायी मेमोरी स्पेस (जैसे StringBuilder के साथ) में स्ट्रिंग प्रतिस्थापन करते समय, यह महंगा है। यदि प्रतिस्थापन स्ट्रिंग मूल स्ट्रिंग की तुलना में एक अलग लंबाई है, तो आप पूरे स्ट्रिंग को लगातार रखने के लिए प्रतिस्थापन स्ट्रिंग के बाद प्रत्येक वर्ण को स्थानांतरित करने जा रहे हैं। यह बहुत मेमोरी में लिखता है, और यहां तक ​​कि स्ट्रिंगबिलडर के मामले में, आपको बदलने के लिए प्रत्येक कॉल पर स्ट्रिंग इन-मेमोरी को पुनः लिखना पड़ता है।

तो स्ट्रिंग बदली करने का सबसे तेज़ तरीका क्या है? सिंगल-पास का उपयोग करके नई स्ट्रिंग लिखें: अपना कोड वापस मत दो और फिर से कुछ भी लिखना होगा। लिखता है पढ़ता से ज्यादा महंगे हैं। आपको सबसे अच्छे परिणाम के लिए खुद को कोड करना होगा।

उच्च स्मृति समाधान

मैंने लिखा वर्ग टेम्पलेट्स के आधार पर तार उत्पन्न करता है मैं एक टेम्प्लेट में टोकन ($ प्रतिस्थापन $ $) रखता हूं जो ऐसे स्थानों को चिह्नित करता है जहां मैं बाद में एक स्ट्रिंग सम्मिलित करना चाहता हूं। मैं उन मामलों में इसका उपयोग करता हूं जहां एक्सएमएलआरआईएम एक्सएमएल के लिए बहुत भारी है जो काफी हद तक स्थिर और दोहरावदार है, और मुझे बड़ा एक्सएमएल (या जेएसओएन) डाटा स्ट्रीम बनाने की आवश्यकता है।

क्लास को टेम्पलेट को टुकड़ों को टुकड़ों में टुकड़े टुकड़े करके और प्रत्येक भाग को गिने शब्दकोष में स्थानांतरित करता है। पैरामीटर भी एन्यूमरेटेड हैं। जिस क्रम में एक नई स्ट्रिंग में भागों और पैरामीटर डाली जाती हैं, उन्हें एक पूर्णांक सरणी में रखा जाता है। जब कोई नई स्ट्रिंग उत्पन्न होती है, तो भागों और पैरामीटर को शब्दकोश से चुना जाता है और एक नया स्ट्रिंग बनाने के लिए उपयोग किया जाता है।

यह न तो पूरी तरह से अनुकूलित है और न ही बुलेटप्रूफ है, लेकिन यह टेम्पलेट्स से बहुत बड़ी डेटा स्ट्रीम बनाने के लिए बहुत अच्छा काम करता है।

कम स्मृति समाधान

आपको स्रोत स्ट्रिंग से एक छोटी बफर को बफर में पढ़ना होगा, बफर को एक अनुकूलित खोज एल्गोरिदम का उपयोग करके खोज करना होगा, और फिर गंतव्य स्ट्रीम / स्ट्रिंग में नई स्ट्रिंग लिखें। यहां कई संभावित चेतावनियां हैं, लेकिन यह स्मृति कुशल और स्रोत डेटा के लिए एक बेहतर समाधान होगा जो कि गतिशील है और कैश नहीं किया जा सकता है, जैसे संपूर्ण पेज अनुवाद या स्रोत डेटा जो कि यथोचित कैश के लिए बहुत बड़ा है। मेरे पास इस काम के लिए एक नमूना समाधान नहीं है।

नमूना कोड

वांछित परिणाम

 <DataTable source='Users'> <Rows> <Row id='25' name='Administrator' /> <Row id='29' name='Robert' /> <Row id='55' name='Amanda' /> </Rows> </DataTable> 

खाका

 <DataTable source='$TableName$'> <Rows> <Row id='$0$' name='$1$'/> </Rows> </DataTable> 

परीक्षण का मामला

 class Program { static string[,] _users = { { "25", "Administrator" }, { "29", "Robert" }, { "55", "Amanda" }, }; static StringTemplate _documentTemplate = new StringTemplate(@"<DataTable source='$TableName$'><Rows>$Rows$</Rows></DataTable>"); static StringTemplate _rowTemplate = new StringTemplate(@"<Row id='$0$' name='$1$' />"); static void Main(string[] args) { _documentTemplate.SetParameter("TableName", "Users"); _documentTemplate.SetParameter("Rows", GenerateRows); Console.WriteLine(_documentTemplate.GenerateString(4096)); Console.ReadLine(); } private static void GenerateRows(StreamWriter writer) { for (int i = 0; i <= _users.GetUpperBound(0); i++) _rowTemplate.GenerateString(writer, _users[i, 0], _users[i, 1]); } } 

स्ट्रिंगमाइटलेट स्रोत

 public class StringTemplate { private string _template; private string[] _parts; private int[] _tokens; private string[] _parameters; private Dictionary<string, int> _parameterIndices; private string[] _replaceGraph; private Action<StreamWriter>[] _callbackGraph; private bool[] _graphTypeIsReplace; public string[] Parameters { get { return _parameters; } } public StringTemplate(string template) { _template = template; Prepare(); } public void SetParameter(string name, string replacement) { int index = _parameterIndices[name] + _parts.Length; _replaceGraph[index] = replacement; _graphTypeIsReplace[index] = true; } public void SetParameter(string name, Action<StreamWriter> callback) { int index = _parameterIndices[name] + _parts.Length; _callbackGraph[index] = callback; _graphTypeIsReplace[index] = false; } private static Regex _parser = new Regex(@"\$(\w{1,64})\$", RegexOptions.Compiled); private void Prepare() { _parameterIndices = new Dictionary<string, int>(64); List<string> parts = new List<string>(64); List<object> tokens = new List<object>(64); int param_index = 0; int part_start = 0; foreach (Match match in _parser.Matches(_template)) { if (match.Index > part_start) { //Add Part tokens.Add(parts.Count); parts.Add(_template.Substring(part_start, match.Index - part_start)); } //Add Parameter var param = _template.Substring(match.Index + 1, match.Length - 2); if (!_parameterIndices.TryGetValue(param, out param_index)) _parameterIndices[param] = param_index = _parameterIndices.Count; tokens.Add(param); part_start = match.Index + match.Length; } //Add last part, if it exists. if (part_start < _template.Length) { tokens.Add(parts.Count); parts.Add(_template.Substring(part_start, _template.Length - part_start)); } //Set State _parts = parts.ToArray(); _tokens = new int[tokens.Count]; int index = 0; foreach (var token in tokens) { var parameter = token as string; if (parameter == null) _tokens[index++] = (int)token; else _tokens[index++] = _parameterIndices[parameter] + _parts.Length; } _parameters = _parameterIndices.Keys.ToArray(); int graphlen = _parts.Length + _parameters.Length; _callbackGraph = new Action<StreamWriter>[graphlen]; _replaceGraph = new string[graphlen]; _graphTypeIsReplace = new bool[graphlen]; for (int i = 0; i < _parts.Length; i++) { _graphTypeIsReplace[i] = true; _replaceGraph[i] = _parts[i]; } } public void GenerateString(Stream output) { var writer = new StreamWriter(output); GenerateString(writer); writer.Flush(); } public void GenerateString(StreamWriter writer) { //Resolve graph foreach(var token in _tokens) { if (_graphTypeIsReplace[token]) writer.Write(_replaceGraph[token]); else _callbackGraph[token](writer); } } public void SetReplacements(params string[] parameters) { int index; for (int i = 0; i < _parameters.Length; i++) { if (!Int32.TryParse(_parameters[i], out index)) continue; else SetParameter(index.ToString(), parameters[i]); } } public string GenerateString(int bufferSize = 1024) { using (var ms = new MemoryStream(bufferSize)) { GenerateString(ms); ms.Position = 0; using (var reader = new StreamReader(ms)) return reader.ReadToEnd(); } } public string GenerateString(params string[] parameters) { SetReplacements(parameters); return GenerateString(); } public void GenerateString(StreamWriter writer, params string[] parameters) { SetReplacements(parameters); GenerateString(writer); } } 
 StringBuilder sb = new StringBuilder("Hello string"); sb.Replace("string", String.Empty); Console.WriteLine(sb); 

स्ट्रिंगबिल्डर, एक अस्थायी स्ट्रिंग

यदि आप चाहते हैं कि dotnet में एक क्लास में निर्मित हो तो मुझे लगता है कि स्ट्रिंगब्युल्डर सबसे अच्छा है। इसे मज़बूत बनाने के लिए आप असुरक्षित कोड का इस्तेमाल कर सकते हैं * चार * और अपनी स्ट्रिंग के माध्यम से फिर से और आपके मानदंडों के आधार पर बदल सकते हैं

चूंकि आपके पास एकाधिक स्ट्रिंग पर जगह है, इसलिए मैं आपको स्ट्रिंगबिल्टर पर RegEx का उपयोग करने के लिए wolud की सिफारिश करता हूं।