2011-04-15 10 views
7

से भी खराब है, मैं और जानने के लिए अलग-अलग प्रश्नों के उत्तर की समीक्षा कर रहा था। मैं एक answer जो कहता है कि यह php में बुरा व्यवहारक्यों गणना गिनती

 
for($i=0;$i<count($array);$i++) 

लिखने के लिए यह कहना है कि पाश में गिनती समारोह बुला कोड की गति कम कर देता है देखा। इस प्रश्न पर टिप्पणियों में चर्चा स्पष्ट नहीं थी। मैं जानना चाहता हूं कि यह अच्छा अभ्यास क्यों नहीं है। ऐसा करने का वैकल्पिक तरीका क्या होना चाहिए?

उत्तर

8

आप इस बजाय करना चाहिए:

$count = count($array); 
for($i=0;$i<$count;$i++)... 

ऐसा करने के लिए कारण है अगर आप पाश के लिए अंदर count($array) डाल तो गिनती समारोह हर यात्रा जो नीचे की गति को धीमा करने का आह्वान करना होगा क्योंकि।

हालांकि, यदि आप एक चर में गिनती डालते हैं, तो यह एक स्थिर संख्या है जिसे हर बार पुन: गणना नहीं करना पड़ेगा।

+0

लेकिन इसका कारण क्या है? –

+0

@Awais मैंने – Neal

4

प्रत्येक पुनरावृत्ति के लिए, PHP लूप के उस हिस्से को देख रहा है (स्थिति) यह देखने के लिए कि क्या इसे लूपिंग रखना चाहिए, और हर बार जब यह जांचता है, तो यह सरणी की लंबाई की गणना कर रहा है।

एक आसान तरीका है करने के लिए कैश कि मूल्य है ...

for($i=0,$count=count($array);$i<$count;$i++) { ... } 

यह शायद छोटे छोरों में आवश्यक नहीं है, लेकिन जब आइटम के हजारों से अधिक पुनरावृत्ति एक बड़ा फर्क कर सकता है, और क्या पर निर्भर है फ़ंक्शन कॉल हालत में है (और यह इसके वापसी मूल्य को कैसे निर्धारित करता है)।

यही कारण है कि आपको foreach() { ... } का उपयोग करना चाहिए यदि आप कर सकते हैं, तो यह सेट पर लूप के लिए सरणी की एक प्रति पर एक इटरेटर का उपयोग करता है और आपको लूप की स्थिति को कैशिंग करने की चिंता करने की आवश्यकता नहीं है।

+0

कारण जोड़ा है आपका मतलब है कि foreach loop सरणी की प्रति रखता है? क्षमा करें मुझे समझ में नहीं आया। –

+1

@Awais हां, इससे पहले कि यह एक प्रतिलिपि बनाता है, इसे रीसेट करता है और मूल के बजाए इसके पॉइंटर को आगे बढ़ाता है। – alex

+0

अच्छा है लेकिन अगर हमारे पास बहुत बड़ी सरणी है तो क्या यह एक व्यवहार्य समाधान है कि एक लूप में प्रतिलिपि के साथ-साथ मूल सरणी भी होती है? –

1

यह अच्छी प्रथा नहीं है क्योंकि लिखित के रूप में, count($array) प्रत्येक बार लूप के माध्यम से बुलाया जाएगा। मान लें कि आप लूप के भीतर सरणी के आकार को नहीं बदलेंगे (जो स्वयं ही एक भयानक विचार होगा), यह फ़ंक्शन हमेशा एक ही मान वापस कर देगा, और इसे बार-बार कॉल करना अनावश्यक है।

लघु लूप के लिए, अंतर शायद ध्यान देने योग्य नहीं होगा, लेकिन यह अभी भी एक बार फ़ंक्शन को कॉल करना और लूप में गणना मूल्य का उपयोग करना सबसे अच्छा है।

3

मैंने डॉक्टर की सर्जरी में एक डेटाबेस के बारे में सुना जिसने सॉफ्टवेयर के एक टुकड़े के साथ वास्तव में यह गलती की। यह लगभग 100 रिकॉर्ड के साथ परीक्षण किया गया था, सब ठीक काम किया। कुछ महीनों के भीतर, यह लाखों रिकॉर्ड से निपट रहा था और परिणामों को लोड करने में कुछ मिनट लग रहा था, पूरी तरह से अनुपयोगी था। कोड को ऊपर दिए गए उत्तरों के अनुसार प्रतिस्थापित किया गया था, और यह पूरी तरह से काम किया।

इसके बारे में सोचने के लिए, एक काफी शक्तिशाली समर्पित सर्वर जो अधिक कुछ नहीं कर रहा है, गिनती ($ सरणी) करने के लिए लगभग 1 नैनोसेकंड लेगा। यदि आपके पास लूप के लिए 100 था, तो प्रत्येक 1,000 पंक्तियों की गणना करता है, तो यह केवल एक सेकंड का 0.0001 है।

हालांकि, यह प्रत्येक पृष्ठ लोड के लिए 100,000 गणना है। स्केल करें कि 1,000,000 उपयोगकर्ता (और जो 1 मिलियन उपयोगकर्ता नहीं चाहते हैं?) ... 10 पेज लोड कर रहे हैं और अब आपके पास 1,000,000,000,000 (1 ट्रिलियन) गणनाएं हैं। यह सर्वर पर बहुत अधिक भार डालने जा रहा है। यह एक 1,000 सेकंड (लगभग 16.5 मिनट) है कि आपका प्रोसेसर उस कोड को चलाता है।

अब कोड को संसाधित करने के लिए मशीन लेता है, सरणी में वस्तुओं की संख्या, और कोड में लूप की संख्या ... आप सचमुच कई ट्रिलियन प्रक्रियाओं और कई घंटों की बात कर रहे हैं उस प्रक्रिया को संसाधित करने के लिए जिसे पहले एक चर में परिणाम संग्रहीत करके टाला जा सकता है।

+0

+1 .... –

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