2012-04-15 15 views
6

यह some other question में चर्चा से एक स्पिन-ऑफ है।स्ट्रिंग विभाजन के बिना पार्स

मान लीजिए कि मुझे बहुत लंबे तारों की एक बड़ी संख्या का विश्लेषण करना है। प्रत्येक स्ट्रिंग में व्हाइटस्पेस द्वारा अलग double एस (निश्चित रूप से पाठ प्रतिनिधित्व में) का अनुक्रम होता है। मुझे double एस को List<double> में पार्स करने की आवश्यकता है।

मानक पार्सिंग तकनीक (string.Split + double.TryParse का उपयोग करके) काफी धीमी प्रतीत होती है: प्रत्येक संख्या के लिए हमें एक स्ट्रिंग आवंटित करने की आवश्यकता होती है।

मैंने इसे पुराने सी-जैसा तरीका बनाने की कोशिश की: शुरुआत के सूचकांक और संख्याओं वाले सबस्ट्रिंग्स के अंत की गणना करें, और अतिरिक्त स्ट्रिंग बनाने के बिना इसे "जगह में" पार्स करें। (http://ideone.com/Op6h0 देखें, प्रासंगिक हिस्सा दिखाया नीचे।)

int startIdx, endIdx = 0; 
while(true) 
{ 
    startIdx = endIdx; 
    // no find_first_not_of in C# 
    while (startIdx < s.Length && s[startIdx] == ' ') startIdx++; 
    if (startIdx == s.Length) break; 
    endIdx = s.IndexOf(' ', startIdx); 
    if (endIdx == -1) endIdx = s.Length; 
    // how to extract a double here? 
} 

string.IndexOf की एक अधिभार, किसी दिए गए स्ट्रिंग के भीतर ही खोज नहीं है, लेकिन मैं-स्ट्रिंग से एक डबल पार्स करने के लिए एक विधि को खोजने में असफल है, वास्तव में निकालने कि बिना पहले सबस्ट्रिंग।

क्या किसी के पास कोई विचार है?

+5

आपने साबित कर यह वास्तव में एक अड़चन है है? मुझे यह करने के किसी भी तरीके से * पता नहीं है, लेकिन मुझे निश्चित रूप से सूक्ष्म अनुकूलन से पहले एक समस्या होने का कुछ सबूत चाहिए। –

+0

@ जोन: वास्तव में नहीं। सवाल लिंक किए गए प्रश्न (http://stackoverflow.com/questions/10053449/extract-numbers-from-string) पर चर्चा पर आधारित है। उसके लिए खेद है। – Vlad

+0

पर्याप्त मेला। मुझे संदेह है कि एक हाथ से लिखित पार्स दिनचर्या संभवतः अनुकूलित-अनुकूलित अनुभव के साथ धीमी होगी-बीसीएल टीम के साथ-साथ बहुत सारी अनुभव विधि :) –

उत्तर

7

कोई प्रबंधित एपीआई एक सबस्ट्रिंग से एक डबल पार्स करने के लिए है। मेरा अनुमान है कि स्ट्रिंग आवंटित करना सभी फ्लोटिंग पॉइंट ऑपरेशंस की तुलना में दोगुना होगा। पर्स।

वैसे भी, आप लंबाई में 100 बार एक बार "बफर" स्ट्रिंग बनाकर आवंटन को बचा सकते हैं जिसमें केवल व्हाइटस्पेस शामिल है। फिर, प्रत्येक स्ट्रिंग के लिए जिसे आप पार्स करना चाहते हैं, आप असुरक्षित कोड का उपयोग करके वर्णों को इस बफर स्ट्रिंग में कॉपी करते हैं। आप सफेद जगह के साथ बफर स्ट्रिंग भरें। और पार्सिंग के लिए आप NumberStyles का उपयोग कर सकते हैं। AllowTrailingWhite जो पिछली सफेद जगह को अनदेखा कर देगा।

string l_pos = new string(' ', 100); //don't write to a shared string! 
    unsafe 
    { 
     fixed (char* l_pSrc = l_pos) 
     {    
       // do some work 
     } 
    } 

सी # एक चार के लिए एक स्ट्रिंग बाध्य करने के लिए * विशेष सिंटेक्स है:

स्ट्रिंग के लिए एक सूचक हो रही है वास्तव में एक पूरी तरह से समर्थित ऑपरेशन है।

+0

क्या मैं सही ढंग से समझता हूं: क्या आप असुरक्षित कोड के साथ एक अनुमानित 'System.String' को संशोधित करना चाहते हैं? – Vlad

+0

क्या सभी व्हाइटस्पेस को पार्सिंग नहीं करना हर बार एक नई स्ट्रिंग आवंटित करने से वास्तव में धीमा कर देता है? – svick

+0

@Vlad, हाँ आप यह कर सकते हैं। बस उस स्ट्रिंग को चारों ओर पास न करें और इसे निजी रखें। इस तरह आप अन्य कोड बनाता है धारणाओं का उल्लंघन नहीं करते हैं। स्ट्रिंगबिल्डर आंतरिक रूप से इस तकनीक का उपयोग करता है। जब आप एक स्ट्रिंगबिल्डर को टॉस्ट्रिंग करते हैं तो यह आपको अपने आंतरिक बफर को हाथ देता है। StringBuilder.ToString अक्सर ओ (1) है। – usr

2

यदि आप यह वास्तव में तेजी से करना चाहते हैं, मैं एक राज्य मशीन

ऐसा दिखाई दे सकता का प्रयोग करेंगे:

enum State 
{ 
    Separator, Sign, Mantisse etc. 
} 
State CurrentState = State.Separator; 
int Prefix, Exponent, Mantisse; 
foreach(var ch in InputString) 
{ 
    switch(CurrentState) 
    { // set new currentstate in dependence of ch and CurrentState 
     case Separator: 
      GotNewDouble(Prefix, Exponent, Mantisse); 


    } 

} 
+0

क्या आपको TryParse का उपयोग किए बिना मैन्युअल पार्सिंग का मतलब है? – Vlad

+0

हां, यदि आप TryParse का उपयोग कर रहे हैं, तो आपको हर बार एक नया स्ट्रिंग उदाहरण चाहिए। तो आपके पास वही व्यवहार है जैसे var value = string.Split ('')। चयन करें (एस => डबल। पर्स (एस))। ToArray(); – user287107

+0

अच्छी तरह से, मैन्युअल पार्सिंग धीमी और छोटी गाड़ी हो जाती है, यदि संभव हो तो मैं पहिया को फिर से शुरू करना चाहता हूं। – Vlad

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