क्या arrays के लिए PHP की गिनती () फ़ंक्शन O (1) या O (n) है?


96

क्या count()वास्तव में एक PHP सरणी के सभी तत्वों को गिना जाता है, या क्या यह मूल्य कहीं कैश किया गया है और बस पुनर्प्राप्त हो जाता है?


6
इसका परीक्षण क्यों नहीं? यह एक लूप करने के लिए पर्याप्त है जो एक सरणी में तत्वों को जोड़ता है और हर बार गिनता है और कुछ समय करता है।
मार्क बी

3
इस प्रश्न पर एक नज़र डालें: stackoverflow.com/questions/2473989/…
Pixel Developer

Google कीवर्ड - इस प्रश्न को इस रूप में भी तैयार किया जा सकता है: क्या PHP काउंट () सरणी पर निर्भर करता है या यह एरे प्रॉपर्टी से काउंट को पुनः प्राप्त करता है?
jave.web 12

जवाबों:


136

खैर, हम स्रोत को देख सकते हैं:

/ext/standard/array.c

PHP_FUNCTION(count)कॉल php_count_recursive(), जो बदले में zend_hash_num_elements()गैर-पुनरावर्ती सरणी के लिए कॉल करता है, जिसे इस तरह से लागू किया जाता है:

ZEND_API int zend_hash_num_elements(const HashTable *ht)
{
    IS_CONSISTENT(ht);

    return ht->nNumOfElements;
}

तो आप देख सकते हैं, यह O(1)है $mode = COUNT_NORMAL


6
IS_CONSISTENT(ht)हालांकि क्या करता है?
मैथ्यू

1
धन्यवाद! मुझे पूरा यकीन नहीं था कि स्रोत में मुझे कहाँ दिखना चाहिए या कहाँ से स्रोत प्राप्त करना चाहिए (बिना किसी भंडार के इसे जाँचने के लिए)।
डेक्सटर

3
@ मैट यह जाँच रहा है कि क्या हैश संरचना वैध है, जैसा कि मैं देख सकता हूँ। इसे zend_hash.c में परिभाषित किया गया है और यह O (1) भी है।
व्लादिस्लाव रैस्ट्रुसनी

10
PHP के स्रोत कोड में जवाब की तलाश में किसी के लिए वोट करने के लिए याद नहीं कर सकते :) :)
लैमी


7

PHP में 5+ लंबाई सरणी में संग्रहीत की जाती है, इसलिए प्रत्येक बार गिनती नहीं की जाती है।

संपादित करें: आप भी इस विश्लेषण को दिलचस्प पा सकते हैं: PHP गणना प्रदर्शन । हालाँकि, सरणी की लंबाई सरणी द्वारा बनाए रखी जाती है, फिर भी ऐसा लगता है जैसे कि अगर आप count()कई बार कॉल करने जा रहे हैं तो इसे पकड़ना तेज़ है ।


मुझे लगता है कि आप सही हो सकते हैं कि परिवर्तन PHP 5 के साथ शुरू किया गया था। हालाँकि, मुझे अभी तक यह प्रमाण नहीं मिला है कि गिनती के लिए PHP 4 O (n) था; मैं सिर्फ एक महत्वपूर्ण टिप्पणी देखता हूं। क्या आप प्रमाण खोजने में सक्षम हैं (यानी PHP 4 के लिए गिनती)? धन्यवाद,
क्रिस्टोफर विंडसर

3

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

उदाहरण के लिए,

$cnt = count($array);
for ($i =0; $i < $cnt; $i++) {
   foo($array[$i]);
}

इसके अतिरिक्त, आप हमेशा यह सुनिश्चित नहीं कर सकते कि countकिसी सरणी पर कॉल किया जा रहा है। यदि इसे किसी ऐसी वस्तु पर बुलाया जाता है जो Countableउदाहरण के लिए लागू होती है, तो countउस वस्तु की विधि कहलाएगी।


एक अनुवर्ती के रूप में आप josephscott.org/archives/2010/01/php-count-performance को पढ़ना चाहते हैं, यह मूल रूप से विवरण देता है कि सरणी की लंबाई ओ (1) कैसे हो रही है और दोहराया फ़ंक्शन कॉल का प्रभाव है।
क्लेयर

1
एक फ़ंक्शन कॉल हमेशा एक नहीं बनाने की तुलना में धीमा है? मुझे इनलाइन ऑप्टिमाइज़ेशन के लिए दुभाषिया खोजने में आश्चर्य नहीं होगा।
corsiKa

1
the count method of that object will be called, क्या आप इसे थोड़ा समझा सकते हैं
स्टील ब्रेन

1
@SteelBrain यदि कोई वर्ग Countableइंटरफ़ेस को लागू करता है, तो कॉलिंग कॉलिंग count($object)के समान है $object->count()। उदाहरण के लिए 3v4l.org/oYSSC देखें ।
mfonda

you're still making a function call when which is slower than not making oneयह कथन गलत हो सकता है। यदि आप मैनुअल ट्रैवर्सल कर रहे हैं, तो वह O(n)ऑपरेशन है। लेकिन अगर आप सिर्फ एक पूर्व गणना मूल्य प्राप्त करना चाहते हैं, तो ऑपरेशन है O(1)
जमशेद अहमद
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.