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