क्या पर्ल के ग्लोब की कोई सीमा है?


9

मैं 5 पात्रों के रिटर्न की उम्मीद कर रहा हूं:

while (glob '{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}'x5) {
  print "$_\n";
}

लेकिन यह केवल 4 अक्षर देता है:

anbc
anbd
anbe
anbf
anbg
...

हालाँकि, जब मैं सूची में वर्णों की संख्या कम करता हूँ:

while (glob '{a,b,c,d,e,f,g,h,i,j,k,l,m}'x5) {
  print "$_\n";
}

यह सही ढंग से लौटता है:

aamid
aamie
aamif
aamig
aamih
...

क्या कोई मुझे बता सकता है कि मैं यहाँ क्या याद कर रहा हूँ, क्या किसी प्रकार की सीमा है? या इस के आसपास एक रास्ता है?

अगर इससे कोई फर्क पड़ता है, तो यह दोनों में एक ही परिणाम देता है perl 5.26औरperl 5.28


इससे पहले: stackoverflow.com/a/58852104 stackoverflow.com/a/58853045 ग्लोब फ़ंक्शन का दुरुपयोग करने के बजाय एक पुनरावृत्ति प्रदान करने वाले मॉड्यूल का उपयोग करें। p3rl.org/Algorithm::Combinatorics p3rl.org/Algorithm::Loops
daxim

साभार @daxim समस्या यह है कि मैं अभी किसी भी प्रकार के मॉड्यूल को लोड करने के लिए संघर्ष कर रहा हूं, मेरे पास Win32 :: कंसोल के बारे में शिकायत करने वाला एक cpan मुद्दा है, फिर भी ppm प्रति पर्ल 5.28 में उपलब्ध नहीं है, इसलिए मैं cpan के लिए मॉड्यूल को लोड कर सकता हूं ताकि शिकायत करना बंद हो सके।
गेरी

धन्यवाद @zdim सभी समय और प्रयास की सराहना करते हैं।
गेरी

मुझे बस एहसास हुआ ... क्या आप इस फेरबदल (यादृच्छिक) को पूरी या पूरी सूची में चाहते हैं?
zdim

@zdim सिर्फ एक पूरी सूची। :)
गेरी

जवाबों:


6

हर चीज में कुछ सीमा होती है।

यहां एक शुद्ध पर्ल मॉड्यूल है जो इसे आपके लिए पुनरावृत्त कर सकता है। यह एक ही बार में पूरी सूची उत्पन्न नहीं करता है और आप तुरंत परिणाम प्राप्त करना शुरू करते हैं:

use v5.10;

use Set::CrossProduct;

my $set = Set::CrossProduct->new( [ ([ 'a'..'z' ]) x 5 ] );

while( my $item = $set->get ) {
    say join '', @$item
    }

यार, तुम समझ नहीं पा रहे हो कि मैं अभी कितना खुश हूं। आपका बहुत बहुत धन्यवाद!!
गेरी

3
एल्गोरिथम :: लूप्स का NestedLoopsउपयोग भी किया जा सकता है: use Algorithm::Loops qw( NestedLoops ); NestedLoops([ ([ 'a'..'z' ]) x 5 ], sub { say join '', @_ } ); (ओपी द्वारा पहले के एक प्रश्न का उत्तर में उल्लेख किया गया है कि वे इसका उपयोग कर सकते हैं यदि वे स्मृति से बाहर चल रहे थे ...)
ikegami

8

globपहले सभी संभव फ़ाइल नाम विस्तार बनाता है, इसलिए यह पहली बार होगा पूरी सूची उत्पन्न खोल शैली ग्लोब / पैटर्न यह दिया जाता है से। इसके बाद ही इस पर पुनरावृत्ति होगी, यदि इसे स्केलर संदर्भ में उपयोग किया जाता है। यही कारण है कि यह थकाऊ से बाहर निकलने के बिना भागने के लिए इतना कठिन (असंभव) है; इस पोस्ट को देखें ।

आपके पहले उदाहरण में वह 26 5 स्ट्रिंग्स ( 11_881_376) है, प्रत्येक पाँच वर्ण लंबा है। तो 56Mb से अधिक (भोले) कुल के साथ ~ 12 मिलियन स्ट्रिंग्स की एक सूची ... प्लस एक स्केलर के लिए ओवरहेड, जो मुझे लगता है कि न्यूनतम 12 बाइट्स या ऐसा है। तो 100Mb के आदेश पर, बहुत कम से कम, एक सूची में वहीं।

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

इसके चारों ओर एक रास्ते के लिए - 5-चार तार की उस सूची को पुनरावृति से उत्पन्न करें, बजाय globइसके कि पर्दे के पीछे अपना जादू चला दें। तो फिर यह बिल्कुल एक समस्या नहीं होनी चाहिए।

हालांकि, मुझे आराम के लिए पूरी बात थोड़ी बड़ी लगती है, उस मामले में भी। मैं वास्तव में एक एल्गोरिथ्म लिखने की सलाह दूंगा जो एक समय में एक सूची तत्व प्रदान करता है (एक "पुनरावृत्त"), और उसी के साथ काम करता है।

कुछ अच्छे पुस्तकालय हैं जो ऐसा कर सकते हैं (और भी बहुत कुछ), जिनमें से कुछ एल्गोरिथम हैं: इस मामले पर पिछली पोस्ट में (और एक टिप्पणी में) लूप्स की सिफारिश की गई, एल्गोरिथ्म :: कॉम्बिनेटरिक्स (एक ही टिप्पणी), Set::CrossProductएक अन्य उत्तर से यहाँ ...

यह भी ध्यान दें कि, जबकि यह एक चतुर उपयोग है glob, पुस्तकालय फाइलों के साथ काम करने के लिए है। सिद्धांत रूप में इसका दुरुपयोग करने के अलावा, मुझे लगता है कि यह वैध प्रविष्टि के लिए प्रत्येक (~ 12 मिलियन) नामों की जांच करेगा ! ( इस पृष्ठ को देखें ।) यह बहुत सारे अनावश्यक डिस्क का काम है। (और यदि आप "ग्लब्स" का उपयोग करना चाहते थे जैसे *या ?कुछ सिस्टम पर यह केवल उन स्ट्रिंग के साथ एक सूची देता है जिसमें वास्तव में फाइलें होती हैं, तो आप चुपचाप अलग परिणाम प्राप्त करेंगे।)


 मुझे 5-चार स्केलर के आकार के लिए 56 बाइट्स मिल रहे हैं। हालांकि यह एक घोषित चर के लिए है, जो कि गुमनाम स्केलर से थोड़ा अधिक हो सकता है, परीक्षण कार्यक्रम में लंबाई -4 स्ट्रिंग्स के साथ वास्तविक कुल आकार वास्तव में भयावह गणना की तुलना में बड़ा परिमाण का एक अच्छा क्रम है। तो असली बात अच्छी तरह से 1Gb के आदेश पर हो सकती है, एक ऑपरेशन में।

अद्यतन   एक साधारण परीक्षण प्रोग्राम जो 5-चार लंबी स्ट्रिंग्स की सूची बनाता है (उसी globदृष्टिकोण का उपयोग करके ) सर्वर-क्लास मशीन पर 15-ईश मिनट के लिए चला और 725 एमबी मेमोरी ले गया।

यह इस सर्वर पर वास्तविक 5-चार लंबी स्ट्रिंग्स की उचित संख्या, प्रतीत होता है कि सही था।


@ गेरी फर्स्ट, मुझे यकीन नहीं है कि समस्या सीमा के साथ है; इसे देखते हुए ... शायद सूची को पहले उत्पन्न करें, पुनरावृत्ति (एक बार में सभी नहीं), और इसे एक उचित सरणी में संग्रहीत करें? यह निश्चित रूप से किसी भी सीमा के पास कहीं भी नहीं मिलेगा, "मुट्ठी भर" 5-चार तार। (यह डायग्नोस्टिक भी है - अगर यह काम करता है तो यह वास्तव में कुछ आंतरिक सीमा है।)
zdim

@ गेरी को मॉड्यूल की आवश्यकता नहीं है --- बस सूची को (पांच-चार तार की) एक सरणी में, पहले टुकड़े टुकड़े करके, एक साथ उपयोग करने के बजाय एक साथ बनाएं glob। (यह कुछ सरल-दिमाग, अन्य एल्गोरिदम की आवश्यकता होगी। शायद मैंने आपके पिछले प्रश्न में क्या पोस्ट किया है? यह अच्छा डिबगिंग है - यदि आप मुद्दों के बिना उस सूची को प्राप्त कर सकते हैं तो आप जानते हैं कि सीमाएं यहां धकेल दी जा रही हैं।) मैंने कुछ आकार अनुमानों को जोड़ा। कि मैं इस पद पर पहुँच रहा हूँ ...
zdim

@ जीरी time perl -MDevel::Size=total_size -wE'$chs = join ",", "a".."z"; @items = glob "{$chs}"x5; say STDERR "Total memory: ", total_size(\@items)/(1024**2), " Mb"... और मुझे जांचने दो ... अब यह 30 सेकंड में चला गया, जो यह पुष्टि करता है कि यहां कैशिंग कैसे काम करता है। मैंने बाहरी उपकरणों के साथ RSS की भी जाँच की जब वह जा रहा था।
zdim

@ जीरी v5.29.2 (~ 600Mb अब) पर समान व्यवहार ... अभी भी इस सर्वर पर उस कैश पर सवारी कर रहा है :)))
zdim

@Gerry परिणाम किसी अन्य सर्वर क्लास मशीन से, v5.16 के साथ - 28 मिनट (जब यह जा रहा था तब कम आंका गया!) और 750Mb। अब 5.29.2 और फिर ~ 600Mb के तहत रीरन करें। सही तार, और उनमें से सही संख्या (बिल्कुल 26**5)
zdim
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.