मेरे पास एक पर्ल स्क्रिप्ट है जो बहुत सारे डेटा को क्रंच करती है। स्ट्रिंग वैरिएबल का एक गुच्छा है जो छोटे से शुरू होता है लेकिन डॉट (कॉन्सटेंटेशन) ऑपरेटर के बार-बार उपयोग के कारण वास्तव में लंबा हो जाता है। इस तरह से स्ट्रिंग को बढ़ाना परिणामस्वरूप बार-बार आवंटन होगा? यदि हां, तो स्ट्रिंग को पूर्व-आवंटित करने का कोई तरीका है?मैं पर्ल में एक स्ट्रिंग को पूर्व-आवंटित कैसे कर सकता हूं?
उत्तर
हां, पूर्व-विस्तारित तार जो आप जानते हैं, बढ़ना एक अच्छा विचार है।
आप ऐसा करने के लिए 'x' ऑपरेटर का उपयोग कर सकते हैं। उदाहरण के लिए, 1000 रिक्त स्थान preallocate रहे हैं:
$ s = "" x 1000:
और उसके बाद असाइनमेंट के lhs पर substr का उपयोग करें। Uuuuugly। – chaos
इस एक स्ट्रिंग 1000 रिक्त स्थान है, जब मैं तो कहते हैं कि "$ s = 'foo'" युक्त बनाने के करते हैं, मैं केवल पहले तीन इस्तेमाल किया के साथ एक 1000-चरित्र स्ट्रिंग मिल जाएगा या यह मुझे एक नया 3-चरित्र स्ट्रिंग दे देंगे और तुम्हारा दूर फेंक दो? (मैं बाद संदेह है, लेकिन वास्तव में नहीं जानता कि कैसे पर्ल यह संभाल लेंगे।) –
आप पुन: असाइन करते हैं, तो यह पुरानी परिणाम फेंक होगा (यह करने के लिए संदर्भ दूर कल्पना करते हुए)। आपको केवल स्ट्रिंग प्रतिस्थापन करने की आवश्यकता होगी, जैसे डेव ने कहा, इसके कुछ हिस्सों को संशोधित करने के लिए। ++ सरणी-फिर-जुड़ें – Anonymous
पर्ल के तार, परिवर्तनशील हैं, इसलिए एक स्ट्रिंग को जोड़कर नहीं एक स्ट्रिंग दोहराव दंड देना है।
आप "तेज़" तरीके खोजने की कोशिश कर सकते हैं, लेकिन यह समयपूर्व अनुकूलन के लिए वास्तव में खराब है।
उदाहरण के लिए, मैंने एक कक्षा को मार दिया जो कड़ी मेहनत को दूर करता था। यह पूरी तरह से काम करता है, लेकिन यह है, इसकी सभी मूर्खतापूर्ण चाल के लिए, वास्तव में धीमा।
Rate magic normal
magic 1.72/s -- -93%
normal 23.9/s 1289% --
हाँ, यह सही है, पर्ल 1200% मैं क्या सोचा था एक सम्मानजनक कार्यान्वयन था की तुलना में तेजी है:
यहाँ परिणाम है।
अपना कोड प्रोफाइल करें और वास्तविक समस्याएं ढूंढें, उन चीज़ों को अनुकूलित करने का प्रयास न करें जो ज्ञात समस्या भी नहीं हैं।
#!/usr/bin/perl
use strict;
use warnings;
{
package MagicString;
use Moose;
has _buffer => (
isa => 'Str',
is => 'rw',
);
has _buffer_size => (
isa => 'Int',
is => 'rw',
default => 0,
);
has step_size => (
isa => 'Int',
is => 'rw',
default => 32768,
);
has _tail_pos => (
isa => 'Int',
is => 'rw',
default => 0,
);
sub BUILD {
my $self = shift;
$self->_buffer(chr(0) x $self->step_size);
}
sub value {
my $self = shift;
return substr($self->{buffer}, 0, $self->{_tail_pos});
}
sub append {
my $self = shift;
my $value = shift;
my $L = length($value);
if (($self->{_tail_pos} + $L) > $self->{_buffer_size }){
$self->{buffer} .= (chr(0) x $self->{step_size});
$self->{_buffer_size} += $self->{step_size};
}
substr($self->{buffer}, $self->{_tail_pos}, $L, $value);
$self->{_tail_pos} += $L;
}
__PACKAGE__->meta->make_immutable;
}
use Benchmark qw(:all :hireswallclock);
cmpthese(-10 , {
magic => sub{
my $x = MagicString->new();
for (1 .. 200001){
$x->append("hello");
}
my $y = $x->value();
},
normal =>sub{
my $x = '';
for (1 .. 200001){
$x .= 'hello';
}
my $y = $x;
}
});
#use Data::Dumper;
#print Dumper(length($x->value()));
कह रहा है कि पर्ल डुप्लिकेट नहीं करता है स्ट्रिंग केवल आधा सच है। पर्ल एक स्ट्रिंग के लिए अतिरिक्त कुछ अक्षर आवंटित करता है, इसलिए पर्ल सबसे अधिक संभावना है कि प्लगिंग को जोड़ते समय स्ट्रिंग युक्त मेमोरी बढ़े। इससे स्मृति की प्रतिलिपि हो सकती है। लेकिन यह आपके सिस्टम के मेमोरी मैनेजर में होता है जो बहुत तेज़ है। याद रखें, ओ (एन) गणित वर्ग में ओ (लॉग) को हरा देगा, लेकिन असली दुनिया में एल्गोरिदम के निरंतर समय मायने रखता है। सी तेज है। – Schwern
दरअसल, ओ (1) बहुत अच्छा नहीं है अगर ओ (1) एक चरण के लिए कई दिन है, जबकि ओ (एन^2) केवल सेकंड ले सकता है :) हालांकि, यदि आपका डेटा आकार इतना बड़ा है तो शायद एक फायदा कि ओ (एन^2) दृष्टिकोण कई हफ्तों से अधिक है और आकार डेटा सेट सामान्य है। –
हां, एक स्ट्रिंग बढ़ने पर पर्ल दोहराए जाने वाले पुनरावृत्ति के परिणामस्वरूप होगा। पर्ल तारों के लिए थोड़ी सी अतिरिक्त जगह आवंटित करता है, लेकिन केवल कुछ बाइट्स। आप इसे डेवेल :: पीक का उपयोग करके देख सकते हैं। यह पुनर्वितरण बहुत तेज़ है और अक्सर वास्तव में स्मृति की प्रतिलिपि नहीं करता है। अपने मेमोरी मैनेजर पर भरोसा करें, यही कारण है कि आप पर्ल में प्रोग्रामिंग कर रहे हैं और सी नहीं। पहले इसे बेंचमार्क करें!
आप $#array = $num_entries
के साथ सरणी को पूर्ववत कर सकते हैं और keys %hash = $num_keys
के साथ हैश लेकिन length $string = $strlen
काम नहीं करता है। यहां एक clever trick I dug up on Perlmonks है।
my $str = "";
vec($str, $length, 8)=0;
$str = "";
या यदि आप एक्सएस में जाना चाहते हैं तो आप SvGROW()
पर कॉल कर सकते हैं।
अराजकता का उपयोग करने के लिए अराजकता का सुझाव और उसके बाद सभी में शामिल होने से स्मृति को दोगुनी से अधिक का उपयोग किया जाएगा। सरणी के लिए मेमोरी। सरणी में प्रत्येक तत्व के लिए आवंटित प्रत्येक स्केलर के लिए मेमोरी। प्रत्येक स्केलर तत्व में आयोजित स्ट्रिंग के लिए मेमोरी। शामिल होने पर प्रतिलिपि के लिए स्मृति। यदि यह सरल कोड में परिणाम देता है, तो ऐसा करें, लेकिन ऐसा नहीं लगता कि आप किसी भी स्मृति को सहेज रहे हैं।
मैं जाना होगा सरणी/जिस तरह से शामिल होने:
push(@array, $crunched_bit)
और फिर $str = join('', @array)
, ज्यादा कुछ नहीं, कुछ बाद में डीबगिंग के लिए सभी तत्वों का उपयोग करने की है।
यह अतिरिक्त मेमोरी का उपयोग करेगा क्योंकि प्रत्येक सरणी तत्व को एक नया एसवी चाहिए। –
मैं विशेष रूप से पता नहीं कैसे पर्ल तार लागू किया जाता है, लेकिन एक बहुत अच्छी अनुमान है कि यह constant amortized time है। इसका मतलब यह है कि भले ही आप के लिए एक रास्ता खोजने के कर पूर्व आवंटित अपने स्ट्रिंग संभावना है कि संयुक्त समय यह सब स्क्रिप्ट के उपयोगकर्ताओं के लिए बचत होगी बार जब आप स्टैक ओवरफ़्लो पर this question पूछ खर्च से भी कम हो जाएगा।
- 1. मैं पर्ल में एक स्ट्रिंग को कैसे लपेट सकता हूं?
- 2. मैं पर्ल में एक स्ट्रिंग को एक नंबर में कैसे परिवर्तित कर सकता हूं?
- 3. पर्ल में, मैं एक विधि को कैसे कॉल कर सकता हूं जिसका नाम स्ट्रिंग में है?
- 4. मैं पर्ल में एक सशर्त प्रतिस्थापन कैसे कर सकता हूं?
- 5. मैं पर्ल में एक सरणी कैसे छोटा कर सकता हूं?
- 6. मैं पर्ल में तिथियों को कैसे क्रमबद्ध कर सकता हूं?
- 7. मैं पर्ल में तिथियों को कैसे सत्यापित कर सकता हूं?
- 8. मैं पर्ल में यूनिक्स grep कैसे कार्यान्वित कर सकता हूं?
- 9. मैं पर्ल में एक शाब्दिक स्ट्रिंग में परिभाषित फ़ंक्शन नाम कैसे कॉल कर सकता हूं?
- 10. मैं एक आईएस 8686 टाइमस्टैम्प को पर्ल में यूनिक्स समय में कैसे परिवर्तित कर सकता हूं?
- 11. मैं थोक खोज कैसे कर सकता हूं और पर्ल के साथ प्रतिस्थापित कैसे कर सकता हूं?
- 12. मैं पर्ल सबराउटिन में दो सरणी और एक स्ट्रिंग कैसे पास कर सकता हूं?
- 13. मैं पर्ल में एक लंबी स्ट्रिंग कैसे उद्धृत कर सकता हूं?
- 14. मैं एक पर्ल स्क्रिप्ट कैसे डिबग कर सकता हूं?
- 15. मैं पर्ल में एक साइबेस डेटाटाइम स्ट्रिंग का उपयोग कैसे कर सकता हूं?
- 16. मैं पर्ल मॉड्यूल को अनलोड कैसे कर सकता हूं?
- 17. पर्ल में स्ट्रिंग की तुलना करते समय मैं उच्चारणों को कैसे नजरअंदाज कर सकता हूं?
- 18. मैं स्ट्रिंग को पर्ल के साथ केवल दो भागों में कैसे विभाजित कर सकता हूं?
- 19. मैं पर्ल में एक्सेल फ़ाइलों को कैसे पढ़ सकता हूं?
- 20. मैं पर्ल में सेट का प्रतिनिधित्व कैसे कर सकता हूं?
- 21. मैं पर्ल में ट्रेसबैक कैसे प्राप्त कर सकता हूं?
- 22. मैं पर्ल में टाइमस्टैम्प कैसे प्रारूपित कर सकता हूं?
- 23. मैं पर्ल में 64-बिट अंकगणित कैसे कर सकता हूं?
- 24. मैं पर्ल में बाइनरी खोज कैसे कार्यान्वित कर सकता हूं?
- 25. मैं पर्ल में यूनिट परीक्षण कैसे कर सकता हूं?
- 26. मैं पर्ल में JSON कैसे पार्स कर सकता हूं?
- 27. मैं पर्ल में सरणी की तुलना कैसे कर सकता हूं?
- 28. मैं Netbeans में एक स्ट्रिंग को कैसे बदल सकता हूं?
- 29. मैं एक नेस्टेड पर्ल हैश को एक गैर-घोंसले में कैसे साफ कर सकता हूं?
- 30. मैं विभाजक की आखिरी घटना पर केवल एक पर्ल स्ट्रिंग कैसे विभाजित कर सकता हूं?
हालांकि सरणी में हर तत्व अपनी भूमि के ऊपर के सभी के साथ एक एसवी पैदा करता है। आप इस तरह से बहुत अधिक स्मृति का उपयोग करेंगे। –