Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

रूबी स्ट्रिंग्स को 13 गुना तेज साफ करना

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

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

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

रिक्त स्थान निकालने के चार तरीके

यहां एक स्ट्रिंग है जो क्रेडिट कार्ड नंबर का प्रतिनिधित्व करती है:"055 444 285"। इसके साथ काम करने के लिए, हम रिक्त स्थान को हटाना चाहते हैं। #gsub यह कर सकता है; #gsub . के साथ आप हर चीज को हर चीज से बदल सकते हैं। लेकिन और भी विकल्प हैं।

string = "055 444 285"
string.gsub(/ /, '')
string.gsub(' ', '')
string.tr(' ', '')
string.delete(' ')
 
# => "055444285"

यह वह अभिव्यंजना है जो मुझे सुविधा विधियों के बारे में सबसे अधिक पसंद है। आखिरी वाला इसका एक अच्छा उदाहरण है:यह "रिक्त स्थान हटाएं" से अधिक स्पष्ट नहीं होता है। विकल्पों के बीच ट्रेड-ऑफ के बारे में सोचना, पठनीयता मेरी पहली प्राथमिकता है, जब तक कि निश्चित रूप से, यह प्रदर्शन समस्याओं का कारण नहीं बनता है। तो, देखते हैं कितना दर्द होता है मेरा पसंदीदा समाधान, #delete वास्तव में कारण बनता है।

मैंने उपरोक्त उदाहरणों को बेंचमार्क किया। आपको इनमें से कौन सी विधि सबसे तेज़ लगती है?

Benchmark.ips do |x|
  x.config(time: 30, warmup: 2)
 
  x.report('gsub')           { string.gsub(/ /, '') }
  x.report('gsub, no regex') { string.gsub(' ', '') }
  x.report('tr')             { string.tr(' ','') }
  x.report('delete')         { string.delete(' ') }
 
  x.compare!
end
अधिकतम से कम से कम निष्पादक के क्रम का अनुमान लगाएं। परिणाम देखने के लिए टॉगल खोलें
Comparison:
  delete:          2326817.5 i/s
  tr:              2121629.8 i/s   - 1.10x  slower
  gsub, no regex:  868184.1 i/s    - 2.68x  slower
  gsub:            474970.5 i/s    - 4.90x  slower

मैं आदेश के बारे में हैरान नहीं था, लेकिन गति में अंतर ने मुझे अभी भी आश्चर्यचकित किया। #gsub न केवल धीमा है, बल्कि पाठक को तर्कों को 'डीकोड' करने के लिए अतिरिक्त प्रयास की भी आवश्यकता है। आइए देखें कि केवल रिक्त स्थान से अधिक की सफाई करते समय यह तुलना कैसे काम करती है।

अपना नंबर चुनें

निम्न फ़ोन नंबर लें:'(408) 974-2414' . मान लें कि हमें केवल संख्यात्मक => 4089742414 . की आवश्यकता है . मैंने एक #scan जोड़ा साथ ही क्योंकि मुझे यह पसंद है कि यह अधिक स्पष्ट रूप से व्यक्त करता है कि हम उन सभी चीजों को हटाने की कोशिश करने के बजाय कुछ विशेष चीजों का लक्ष्य रखते हैं जो हम नहीं चाहते हैं।

Benchmark.ips do |x|
  x.config(time: 30, warmup: 2)
 
  x.report ('gsub')           { string.gsub(/[^0-9] /, '') }
  x.report('tr')              { string.tr("^0-9", "") }
  x.report('delete_chars')    { string.delete("^0-9") }
  x.report('scan')            { string.scan(/[0-9]/).join }
  x.compare!
end
फिर से, ऑर्डर का अनुमान लगाएं, फिर उत्तर देखने के लिए टॉगल खोलें
Comparison:
  delete_chars:   2006750.8 i/s
  tr:             1856429.0 i/s   - 1.08x  slower
  gsub:           523174.7 i/s    - 3.84x  slower
  scan:           227717.4 i/s    - 8.81x  slower

रेगेक्स का उपयोग चीजों को धीमा कर देता है, यह आश्चर्य की बात नहीं है। और इरादा #scan . की अभिव्यक्ति को प्रकट करता है हमें महंगा पड़ता है। लेकिन यह देखते हुए कि रूबी के विशेष तरीके सफाई को कैसे संभालते हैं, मुझे और अधिक का स्वाद मिला।

पैसे पर

आइए सबस्ट्रिंग को हटाने के कुछ तरीके आज़माएं "€ " स्ट्रिंग से "€ 300" . निम्नलिखित में से कुछ समाधान सटीक सबस्ट्रिंग निर्दिष्ट करते हैं "€ " , कुछ बस सभी मुद्रा प्रतीकों या सभी गैर-संख्यात्मक वर्णों को हटा देंगे।

Benchmark.ips do |x|
  x.config(time: 30, warmup: 2)
 
  x.report('delete specific chars')  { string.delete("€ ") }
  x.report('delete non-numericals')  { string.delete("^0-9") }
  x.report('delete prefix')          { string.delete_prefix("€ ") }
  x.report('delete prefix, strip')   { string.delete_prefix("€").strip }
 
  x.report('gsub')                   { string.gsub(/€ /, '') }
  x.report('gsub-non-nums')          { string.gsub(/[^0-9]/, '') }
  x.report('tr')                     { string.tr("€ ", "") }
  x.report('slice array')            { string.chars.slice(2..-1).join }
  x.report('split')                  { string.split.last }
  x.report('scan nums')              { string.scan(/\d/).join }
  x.compare!
end

आप उम्मीद कर सकते हैं, और सही ढंग से, कि विजेता #delete . में से एक है एस। लेकिन इनमें से कौन सा #delete वेरिएंट क्या आप सबसे तेज़ होने की उम्मीद करते हैं? साथ ही:अन्य तरीकों में से एक #delete . की तुलना में तेज़ है एस। कौन सा?

अनुमान लगाएं और फिर खोलें।
Comparison:
        delete prefix:   4236218.6 i/s
 delete prefix, strip:   3116439.6 i/s - 1.36x  slower
                split:   2139602.2 i/s - 1.98x  slower
delete non-numericals:   1949754.0 i/s - 2.17x  slower
delete specific chars:   1045651.9 i/s - 4.05x  slower
                   tr:   951352.0 i/s  - 4.45x  slower
          slice array:   681196.2 i/s  - 6.22x  slower
                 gsub:   548588.3 i/s  - 7.72x  slower
        gsub-non-nums:   489744.8 i/s  - 8.65x  slower
            scan nums:   418978.8 i/s  - 10.11x  slower

मुझे आश्चर्य हुआ कि किसी सरणी को काटना भी #gsub . से तेज़ है और मुझे यह देखकर हमेशा खुशी होती है कि #split . कितनी तेजी से है। और ध्यान दें कि सभी गैर-संख्यात्मक को हटाना किसी विशिष्ट सबस्ट्रिंग को हटाने की तुलना में तेज़ है।

पैसे का पालन करें

चलिए नंबर के बाद करेंसी निकालते हैं। (मैंने धीमे #gsub को छोड़ दिया वेरिएंट।)

Benchmark.ips do |x|
  x.config(time: 30, warmup: 2)
 
  x.report('gsub')                        { string.gsub(/ USD/, '')
  x.report('tr')                          { string.tr(" USD", "") }
  x.report('delete_chars')                { string.delete("^0-9")
  x.report('delete_suffix')               { string.delete_suffix(" USD") }
  x.report('to_i.to_s')                   { string.to_i.to_s }
  x.report("split")                       { string.split.first }
  x.compare!
end

विजेताओं के बीच एक ड्रा है। सबसे तेज़ होने के लिए आप किस 2 से प्रतिस्पर्धा करने की उम्मीद करते हैं?

और:अनुमान लगाएं _कितना_ धीमा `#gsub` आ गया है।
Comparison:
delete_suffix: 4354205.4 i/s
to_i.to_s: 4307614.6 i/s - same-ish: difference falls within error
split: 2870187.8 i/s - 1.52x slower
delete_chars: 1989566.1 i/s - 2.19x slower
tr: 1853957.1 i/s - 2.35x slower
gsub: 524080.6 i/s - 13.22x slower

हमेशा एक विशेष विधि नहीं होती है जो आपकी आवश्यकताओं के अनुरूप हो। आप #to_i का उपयोग नहीं कर सकते यदि आपको एक अग्रणी "0" रखने की आवश्यकता है। और #delete_suffix इस धारणा पर बहुत अधिक निर्भर करता है कि मुद्रा अमेरिकी डॉलर है।

विशिष्ट विधियाँ सटीक उपकरण की तरह हैं - एक विशिष्ट संदर्भ में एक विशिष्ट कार्य के लिए उपयुक्त। तो हमेशा ऐसे मामले होंगे जहां #gsub ठीक वही है जो हमें चाहिए। यह बहुमुखी है, और यह हमेशा दिमाग में सबसे ऊपर होता है। लेकिन इसे संसाधित करना थोड़ा कठिन हो सकता है और अक्सर धीमी, यहां तक ​​​​कि मेरी अपेक्षा से भी धीमी होती है। मेरे लिए, रूबी की समृद्धि भी एक कारण है जिसके साथ काम करने में इतना मज़ा आता है। स्पीड जीत एक अच्छा बोनस है।


  1. रूबी स्ट्रिंग स्वरूपण

    आइए बात करते हैं कि आप रूबी में स्ट्रिंग्स को कैसे प्रारूपित कर सकते हैं। आप एक स्ट्रिंग को प्रारूपित क्यों करना चाहेंगे? ठीक है, हो सकता है कि आप ऐसे काम करना चाहें जैसे संख्या 10 से कम हो (उदाहरण:01, 02, 03…), या कुछ कंसोल आउटपुट कॉलम में अच्छी तरह से स्वरूपित हो। अन्य भाषाओं में आप printf . का

  1. रूबी में बचने वाले पात्र

    इस पोस्ट में हम रूबी में बचने वाले पात्रों के बारे में बात करने जा रहे हैं। हम सीखेंगे कि पात्रों से कैसे बचें, यह कैसे काम करता है, और कुछ उपयोग के मामलों में पूरी तरह से बचने से कैसे बचें। अगर आपको लगता है कि आप \ . के बारे में सब कुछ जानते हैं , यह सब पढ़ना सुनिश्चित करें और आश्चर्यचकित हो जाएं.

  1. जावा में स्ट्रिंग्स की तुलना कैसे करें

    समानता के लिए स्ट्रिंग्स की तुलना करने के लिए, आपको स्ट्रिंग ऑब्जेक्ट के equals का उपयोग करना चाहिए या equalsIgnoreCase तरीके। हम यह भी देखेंगे कि हमें == . का उपयोग क्यों नहीं करना चाहिए स्ट्रिंग की तुलना करने के लिए ऑपरेटर। स्ट्रिंग्स की बराबरी() विधि से तुलना करना अगर हमें जावा में दो स्ट्रिंग्स