खाली सरणियों के लिए जाँच: खाली बनाम गिनती


98

यह सवाल ' कैसे बताऊं अगर एक PHP सरणी खाली है ' तो मुझे इस प्रश्न के बारे में सोचना था

क्या कोई कारण है countजिसका उपयोग emptyयह निर्धारित करने के बजाय किया जाना चाहिए कि कोई सरणी खाली है या नहीं?

मेरा व्यक्तिगत विचार यह होगा कि 2 खाली सरणियों के मामले के लिए समान हैं जिन्हें आपको उपयोग करना चाहिए emptyक्योंकि यह बूलियन प्रश्न का एक बूलियन जवाब देता है। ऊपर दिए गए प्रश्न से, ऐसा लगता है कि count($var) == 0यह लोकप्रिय तरीका है। मेरे लिए, जबकि तकनीकी रूप से सही है, कोई मतलब नहीं है। जैसे Q: $ var, क्या आप खाली हैं? A: 7 । हममम ...

क्या कोई कारण है जो मुझे count == 0इसके बजाय या केवल व्यक्तिगत स्वाद का उपयोग करना चाहिए ?

जैसा कि अब हटाए गए उत्तर के लिए टिप्पणियों में अन्य लोगों द्वारा बताया गया है, countबड़े सरणियों के लिए प्रदर्शन प्रभाव पड़ेगा क्योंकि इसे सभी तत्वों को गिनना होगा, जबकि emptyजैसे ही यह पता चलेगा कि यह खाली नहीं है। इसलिए, यदि वे इस मामले में समान परिणाम देते हैं, लेकिन countसंभावित रूप से अक्षम हैं, तो हम कभी क्यों उपयोग करेंगे count($var) == 0?


मैं मान रहा हूं कि बातचीत को विशेष रूप से सरणियों तक सीमित करना है, लेकिन यह ध्यान देने योग्य हो सकता है कि यदि आप वस्तुओं के साथ काम कर रहे हैं (जैसे कि गणनीय, Iterator, आदि को लागू करें) तो खेल पूरी तरह से बदल जाता है।

9
एक खाली सरणी falsePHP के बराबर है - के लिए कोई ज़रूरत नहीं है empty()या नहीं count()
कोबी

@ कोड कोड कृपया।
TheRealChx101

@ TheRealChx101 जैसा कि, बस करें: if (!$myArray) { echo "array is empty"; } sandbox.onlinephpfunctions.com/code/…
Cobby

आजकल, लिंक किए गए प्रश्न में लोकप्रिय विकल्प का उपयोग कर रहा है empty()
फोनिक्स

जवाबों:


97

मैं आमतौर पर उपयोग करता हूं empty। मुझे यकीन नहीं है कि लोग वास्तव में गिनती का उपयोग क्यों करेंगे - यदि सरणी बड़ी है तो गिनती में अधिक समय लगता है / अधिक ओवरहेड होता है। यदि आपको बस यह जानना है कि सरणी खाली है या नहीं, तो खाली का उपयोग करें।


4
सरणी खाली नहीं होने पर ये कार्य वास्तव में भिन्न होते हैं ।
जैको

2
@ तंबाकू: मैं विवादित नहीं हूं। लेकिन अगर आप इसका खाली परीक्षण कर रहे हैं, तो मुझे यह नहीं दिखता कि इसकी क्या प्रासंगिकता है - इसका एक बूलियन परिणाम के साथ एक सवाल है कि फ़ंक्शन क्या वापस आएगा। जब तक न तो खाली माना जाता है के संबंध में देखें कि कैसे उन मानदंडों को गलत जवाब का उत्पादन होगा जब तक कि आपके परीक्षण एक सरणी inwhich मामले में एक पूरी तरह से अलग मुद्दा नहीं है।
प्रोडूयसालसन 16

23
@prodigitalson मैं कहूँगा कि गिनती है O(1), क्योंकि PHP तत्वों की संख्या को आंतरिक रूप से संग्रहीत करता है। इस उत्तर की जाँच करें stackoverflow.com/a/5835419/592454
elitalon

4
@eliton: लेकिन फिर भी - अगर प्रदर्शन में कोई अंतर नहीं है, तो भी गिनती का उपयोग क्यों करें यदि आपको गिनती की आवश्यकता नहीं है?
prodigitalson

4
खाली () त्रुटियों के लिए बहुत क्षमा है। मैंने सिर्फ 2 घंटे बिताए एक उपवर्ग डिबगिंग का परीक्षण किया जो अपने सुपरक्लास के एक निजी सदस्य चर पर खाली () का परीक्षण करता है (सुपरक्लास के सदस्य चर SHOULD के दायरे की रक्षा की गई है, लेकिन खाली) (कोई त्रुटि नहीं लौटाया - परिणाम केवल इतना है कि कुछ होना चाहिए हुआ, नहीं हुआ: उपवर्ग में सदस्य चर का गैर-अस्तित्व बिल्कुल उसी तरह से व्यवहार किया गया था जैसे कि यह सदस्य चर, एक सरणी, खाली था - (जैसे कि इसमें कोई तत्व नहीं था)। यह समस्याग्रस्त है, और PHP का एक और उदाहरण बहुत क्षमाशील है।
मैथ्यू Slyman

47

मैं यह देखने के लिए उत्सुक था कि वास्तव में कौन सा तेज था इसलिए मैंने उन कार्यों को बेंचमार्क करने के लिए एक सरल स्क्रिप्ट बनाई।

<?php

function benchmark($name, $iterations, $action){
    $time=microtime(true);
    for($i=0;$i<=$iterations;++$i){
        $action();
    }
    echo $name . ' ' . round(microtime(true)-$time, 6) . "\n";
}

$iterations = 1000000;
$x = array();
$y = range(0, 10000000);
$actions = array(
    "Empty empty()" => function() use($x){
        empty($x);
    },
    "Empty count()" => function() use($x){
        count($x);
    },
    "Full empty()" => function() use($y){
        empty($y);
    },
    "Full count()" => function() use($y){
        count($y);
    },
    ############
    "IF empty empty()" => function() use($x){
        if(empty($x)){ $t=1; }
    },
    "IF empty count()" => function() use($x){
        if(count($x)){ $t=1; }
    },
    "IF full empty()" => function() use($y){
        if(empty($y)){ $t=1; }
    },
    "IF full count()" => function() use($y){
        if(count($y)){ $t=1; }
    },
    ############
    "OR empty empty()" => function() use($x){
        empty($x) OR $t=1;
    },
    "OR empty count()" => function() use($x){
        count($x) OR $t=1;
    },
    "OR full empty()" => function() use($y){
        empty($y) OR $t=1;
    },
    "OR full count()" => function() use($y){
        count($y) OR $t=1;
    },
    ############
    "IF/ELSE empty empty()" => function() use($x){
        if(empty($x)){ $t=1; } else { $t=2; }
    },
    "IF/ELSE empty count()" => function() use($x){
        if(count($x)){ $t=1; } else { $t=2; }
    },
    "IF/ELSE full empty()" => function() use($y){
        if(empty($y)){ $t=1; } else { $t=2; }
    },
    "IF/ELSE full count()" => function() use($y){
        if(count($y)){ $t=1; } else { $t=2; }
    },
    ############
    "( ? : ) empty empty()" => function() use($x){
        $t = (empty($x) ? 1 : 2);
    },
    "( ? : ) empty count()" => function() use($x){
        $t = (count($x) ? 1 : 2);
    },
    "( ? : ) full empty()" => function() use($y){
        $t = (empty($y) ? 1 : 2);
    },
    "( ? : ) full count()" => function() use($y){
        $t = (count($y) ? 1 : 2);
    }
);

foreach($actions as $name => $action){
    benchmark($name, $iterations, $action);
}
//END

चूंकि मैं यह कर रहा था, मैंने प्रदर्शन करने वाले ऑपरेशनों की जांच करने की भी कोशिश की, जो सामान्य रूप से गिनती () / खाली () के साथ जुड़े होंगे।

PHP 5.4.39 का उपयोग करना:

Empty empty() 0.118691
Empty count() 0.218974
Full empty() 0.133747
Full count() 0.216424
IF empty empty() 0.166474
IF empty count() 0.235922
IF full empty() 0.120642
IF full count() 0.248273
OR empty empty() 0.123875
OR empty count() 0.258665
OR full empty() 0.157839
OR full count() 0.224869
IF/ELSE empty empty() 0.167004
IF/ELSE empty count() 0.263351
IF/ELSE full empty() 0.145794
IF/ELSE full count() 0.248425
( ? : ) empty empty() 0.169487
( ? : ) empty count() 0.265701
( ? : ) full empty() 0.149847
( ? : ) full count() 0.252891

हिपहॉप वीएम 3.6.1 (डीबीजी) का उपयोग करना

Empty empty() 0.210652
Empty count() 0.212123
Full empty() 0.206016
Full count() 0.204722
IF empty empty() 0.227852
IF empty count() 0.219821
IF full empty() 0.220823
IF full count() 0.221397
OR empty empty() 0.218813
OR empty count() 0.220105
OR full empty() 0.229118
OR full count() 0.221787
IF/ELSE empty empty() 0.221499
IF/ELSE empty count() 0.221274
IF/ELSE full empty() 0.221879
IF/ELSE full count() 0.228737
( ? : ) empty empty() 0.224143
( ? : ) empty count() 0.222459
( ? : ) full empty() 0.221606
( ? : ) full count() 0.231288

यदि आप PHP का उपयोग कर रहे हैं तो निष्कर्ष:

  1. खाली () दोनों परिदृश्यों में गिनती () से बहुत तेज है, खाली और आबादी वाले सरणी के साथ

  2. गिनती () पूर्ण या खाली सरणी के साथ एक ही प्रदर्शन करता है।

  3. एक साधारण IF या सिर्फ Boolean ऑपरेशन करना एक समान है।

  4. IF / ELSE ((?) की तुलना में बहुत अधिक कुशल है। जब तक आप बीच में अभिव्यक्ति के साथ अरबों पुनरावृत्तियों कर रहे हैं यह पूरी तरह से महत्वहीन है।

यदि आप HHVM का उपयोग कर रहे हैं तो निष्कर्ष:

  1. खाली () एक नन्हा-नन्हा सा है जो गिनती की तुलना में तेजी से () है, लेकिन तुच्छ रूप से ऐसा है।

    [बाकी PHP में ही है]

निष्कर्ष के निष्कर्ष में, अगर आपको यह जानना आवश्यक है कि क्या सरणी खाली है हमेशा खाली का उपयोग करें ();

यह सिर्फ एक जिज्ञासु परीक्षा थी बस कई चीजों को ध्यान में रखे बिना। यह सिर्फ अवधारणा का प्रमाण है और उत्पादन में संचालन को प्रतिबिंबित नहीं कर सकता है।


नमूना परीक्षण कोड के लिए धन्यवाद .... मैंने अभी इसका इस्तेमाल किया और पाया कि इससे if($x){तेज है if(empty($x)){(केवल काम करता है अगर आपको पता है कि $xघोषित किया गया है)।
रेडजार्फ

आपका परीक्षण कोड वास्तव में खराब है। आप बहुत सारे अतिरिक्त सामान जोड़ रहे हैं, जैसे अनाम फ़ंक्शन कॉल। अगर मैं हटाता हूं और मैं सिर्फ नंगे कोड (एक दूसरे के बाद चक्र के लिए) चलाता हूं, तो मुझे एक बड़ा अंतर मिलता है। और मैं उस मामले में तेजी से मतलब है अगर वहाँ रहे हैं countऔर emptyअगर बयान में कॉल नहीं है । तब यह आता है emptyऔर रहता है count। लेकिन नंगे मामले में आपकी तुलना में, खाली दस गुना तेज है! सरल सरणी परीक्षण: 0.104662, खाली: 0.177659, गिनती: PHP 5.6 पर 1.175125 अन्यथा आपका कोड इस संस्करण पर भी वही परिणाम देता है जैसे कि आपका उल्लेख। बस यह नकली परिणाम है।
Golddragon007

16

मुझे लगता है कि यह केवल व्यक्तिगत प्राथमिकता है। कुछ लोग कह सकते हैं emptyकि तेज है (उदाहरण के लिए http://jamessocol.com/projects/count_vs_empty.php ) जबकि अन्य कह सकते हैं कि countयह मूल रूप से सरणियों के लिए बनाया गया था, बेहतर है।emptyअधिक सामान्य है और अन्य प्रकारों पर लागू किया जा सकता है।

php.net countहालांकि के लिए निम्नलिखित चेतावनी देता है :

गिनती () एक चर के लिए 0 सेट कर सकता है जो सेट नहीं है, लेकिन यह एक चर के साथ आरंभीकृत किए गए चर के लिए 0 भी लौटा सकता है। चर सेट होने पर परीक्षण करने के लिए उपयोग () का उपयोग करें।

दूसरे शब्दों में, यदि चर सेट नहीं होता है, तो आपको PHP से यह कहते हुए नोटिस मिलेगा कि यह अपरिभाषित है। इसलिए, उपयोग countकरने से पहले, चर के साथ जांच करना बेहतर होगा isset। यह आवश्यक नहीं है empty


3
यह दिलचस्प countहै कि इसके पक्ष में एक तर्क यह है कि यह मूल रूप से सरणियों के लिए बनाया गया था ... फिर भी ऑब्जेक्ट लागू कर सकते हैं Countable, और आप count()एक मान्य परिणाम प्राप्त करने के लिए स्केलर मान पास कर सकते हैं ।

1
गिनती () कर सकते हैं एक चर सेट नहीं है के लिए 0 लौटने के लिए, लेकिन यह हो सकता है भी ... । अपनी अनिश्चितता को व्यक्त करने के लिए मोडल क्रियाओं का उपयोग करते हुए आधिकारिक प्रलेखन: पी
नवाफल

isset()बिंदु पर सिर्फ एक टिप्पणी । यदि आप PHP में नोटिस के बारे में चिंतित हैं, तो आपको पहले से ही अपनी सरणी घोषित करनी चाहिए। यदि आप PHP को गतिशील रूप से अपनी सरणी घोषित करते हैं, तो आपको उस बिंदु पर भी सूचना मिल जाएगी। मुझे लगता है कि php.net पर चेतावनी का वास्तविक बिंदु यह है कि आपको यह countनिर्धारित करने के लिए उपयोग नहीं करना चाहिए कि कोई सरणी घोषित की गई है या नहीं क्योंकि यह एक खाली सरणी के समान परिणाम प्राप्त करता है।
नूह डंकन

12

क्या कोई कारण है कि एक सरणी खाली है या नहीं यह निर्धारित करते समय रिक्त के बजाय गिनती का उपयोग किया जाना चाहिए?

जब आपको गैर-रिक्त सरणी पर कुछ करने की आवश्यकता होती है, तो यह जानना आवश्यक है कि इसका आकार क्या है:

if( 0 < ( $cnt = count($array) ) )
{
 echo "Your array size is: $cnt";
}
else
 echo "Too bad, your array is empty :(";

लेकिन मैं गिनती का उपयोग करने की सलाह नहीं दूंगा, जब तक कि आप 100% निश्चित नहीं हैं, कि आप जो गिनती कर रहे हैं वह एक सरणी है। हाल ही में मैं कोड डिबगिंग कर रहा हूं, जहां त्रुटि समारोह FALSEमें खाली सरणी के बजाय वापस आ रहा था, और मुझे जो पता चला वह था:

var_dump(count(FALSE));

उत्पादन:

int 1

तो उसके बाद से मैं उपयोग कर रहा हूँ emptyया if(array() === $array)लगता है कि मेरे पास है होना करने के लिए सरणी कि खाली है।


6

count()लगता है कि सरणी-जैसा इंटरफेस लागू करने के साथ बेहतर काम करता है ArrayAccess/Countableempty()इस प्रकार की वस्तुओं के लिए सही रिटर्न देता है, भले ही उनके पास कोई तत्व न हो। आमतौर पर ये कक्षाएं Countableइंटरफ़ेस को लागू करेंगी , इसलिए यदि प्रश्न "क्या इस संग्रह में तत्व हैं?" कार्यान्वयन के बारे में एक धारणा बनाए बिना, फिर count()एक बेहतर विकल्प है।


आप "मतलब है emptyरिटर्न झूठी वस्तुओं के इन प्रकार के लिए भले ही वे कोई तत्व है"?
अवीव

हाँ। किसी वर्ग को यह परिभाषित करने की अनुमति देने के लिए कोई इंटरफ़ेस नहीं है कि यह "खाली" है या नहीं। और यह वास्तव में वहाँ एक होने के लिए कोई मतलब नहीं होगा।
रयान

+1 का उपयोग countकरना एक अधिक लचीला और एक्स्टेंसिबल समाधान होगा यदि कभी आपके कोड को "सामान्य" तरीके से लागू किए गए संग्रह को स्वीकार करने के लिए समझ में आता है ... आईएमओ जो परिभाषित करने के लिए एकमात्र उचित मापदंड हो सकता है यदि आप उपयोग करते हैं countया अन्य तरीके ...
क्लेम सी सी

count()7.2 के रूप में विशाल नकारात्मक पक्ष यह है कि यह अब खाली चर नहीं ले सकता है।
रयान

5

वैकल्पिक रूप से, आप चर को बूलियन के रूप में डाल सकते हैं (स्पष्ट या स्पष्ट रूप से):

if( $value )
{
  // array is not empty
}

if( (bool) $value )
{
  // array is still not empty
}

E_NOTICEयदि चर को परिभाषित नहीं किया गया है, तो यह विधि उत्पन्न करती है count()

अधिक जानकारी के लिए, टाइप करें तुलना पर PHP मैनुअल पेज देखें ।


1
यह जांचने का सबसे अच्छा तरीका है, केवल तभी उपयोग करें empty()जब आप स्पष्ट रूप से E_NOTICE (जो आमतौर पर एक बुरा विचार है, IMO) को ट्रिगर करने से बचने की कोशिश कर रहे हैं। रिक्त रूप से खाली उपयोग करने से छोटी गाड़ी कोड हो जाएगी।
कोबी

3

मेरी व्यक्तिगत वरीयता लालित्य कोडन के लिए अधिक है (मेरे विशिष्ट उपयोग-मामले के संबंध में)। मैं दान McG inasmuch से सहमत हूं कि गिनती () सही डेटाटाइप (इस मामले में बूलियन) के साथ जवाब देने के लिए नहीं है, इस प्रश्न में परीक्षण के लिए कि डेवलपर को एक 'if' स्टेटमेंट भरने के लिए अधिक कोड लिखने के लिए मजबूर किया जाए।

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

विशेष रूप से जब यह PHP के $ _POST सरणी की बात आती है, तो लिखने / देखने के लिए मेरी राय में यह अधिक "तार्किक" लगता है:

if ( !empty ( $_POST ) ) {
    // deal with postdata
}

3

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

मेरे पास 34 सेकंड थे countऔर 17 सेकंड के लिएempty । दोनों मुझे एक ही गणना देते हैं इसलिए मेरा कोड अभी भी ठीक है।

हालाँकि आप PHP में ==या ===जैसा भी प्रयास कर सकते हैं - जांचें कि क्या दो सरणियाँ समान हैं । सबसे अच्छा मैं कहूंगा कि countबनाम emptyबनाम कोशिश की जाए == empty array, फिर देखें कि कौन सी चीज आपके लिए सर्वश्रेष्ठ है। मेरे मामले countमें सबसे धीमा था इसलिए मैं emptyअभी उपयोग कर रहा हूं ... serializeआगे की जांच होगी


2

count($myArray) == 0ओवर पसंद करने का कोई मजबूत कारण नहीं है empty($myArray)। उनके समान शब्दार्थ हैं। कुछ को एक से अधिक पठनीय मिल सकता है। एक दूसरे की तुलना में बेहतर प्रदर्शन कर सकता है, लेकिन यह php अनुप्रयोगों के विशाल बहुमत में एक महत्वपूर्ण कारक होने की संभावना नहीं है। सभी व्यावहारिक उद्देश्यों के लिए, पसंद स्वाद का विषय है।


1
"प्रदर्शन" चीज़ के बारे में क्या? "व्यावहारिक उद्देश्यों" के स्पष्टीकरण का उपयोग करने से बुरी आदतें पैदा होती हैं। का प्रयोग करें countजब आप गिनती की जरूरत है, का उपयोग करें emptyजब आप यदि संग्रह खाली है की जाँच की जरूरत है। बेशक तार या नल की तरह किनारे के मामले हैं, लेकिन प्रोग्रामर को अपने कोड के बारे में सोचने की जरूरत है। आप असहमत हो सकते हैं, आपको अनुमति दी जाती है।
Namek

कुछ बार, गिनती ($ myArray) के साथ यदि $ myArray एक मान FALSE जैसा बोलेन है, तो गिनती काम नहीं कर रही है (php5.3 पर परीक्षण किया गया)।
ममौनी

1

कभी-कभी खाली का उपयोग करना आवश्यक है। उदाहरण के लिए यह कोड:

$myarray = array();

echo "myarray:"; var_dump($myarray); echo "<br>";
echo "case1 count: ".count($myarray)."<br>";
echo "case1 empty: ".empty($myarray)."<br>";

$glob = glob('sdfsdfdsf.txt');

echo "glob:"; var_dump($glob); echo "<br>";
echo "case2 count: ".count($glob)."<br>";
echo "case2 empty: ".empty($glob);

यदि आप इस कोड को इस तरह चलाते हैं: http://phpfiddle.org/main/code/g9x-uwi

आपको यह आउटपुट मिलता है:

myarray:array(0) { } 
case1 count: 0
case1 empty: 1

glob:bool(false) 
case2 count: 1
case2 empty: 1

तो फिर आप count खाली ग्लोब आउटपुट प्राप्त करते हैं तो आपको गलत आउटपुट मिलता है। आपको शून्यता की जांच करनी चाहिए।

से ग्लोब प्रलेखन:

यदि कोई फ़ाइल मेल नहीं खाती है या त्रुटि पर FALSE है, तो मिलान की गई फ़ाइलों / निर्देशिकाओं वाली एक सरणी देता है।
नोट: कुछ प्रणालियों पर खाली मैच और एक त्रुटि के बीच अंतर करना असंभव है।

इस प्रश्न की भी जांच करें: गणना 1 (झूठी) 1 क्यों?


1

चूंकि एक चर नकारात्मक के रूप में पार्स किया int(1)गया थाcount()

मैं ($array === [] || !$array)एक खाली सरणी के लिए परीक्षण करना पसंद करता हूं ।

हां, हमें एक खाली सरणी की अपेक्षा करनी चाहिए, लेकिन हमें लागू रिटर्न प्रकारों के बिना कार्यों पर अच्छे कार्यान्वयन की उम्मीद नहीं करनी चाहिए।

के साथ उदाहरण हैं count()

var_dump(count(0));
> int(1)
var_dump(count(false));
> int(1)

0

मैं अपने दिमाग के लोगों को धन्यवाद देता हूं, धन्यवाद।

ठीक है, emptyऔर के उपयोग के बीच कोई अंतर नहीं है count। तकनीकी रूप से, countसरणियों के लिए उपयोग किया जाना चाहिए, और emptyसरणियों के साथ-साथ तार के लिए भी इस्तेमाल किया जा सकता है। तो ज्यादातर मामलों में, वे विनिमेय हैं और यदि आप php डॉक्स देखते हैं, countतो आप सुझाव सूची देखेंगे यदि आप हैं emptyऔर इसके विपरीत।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.