2008-10-03 15 views
5

अगर मैं छोरों मैं इनमें से जो सोच रहा हूँ की एक घोंसले में गहरी हूँ और अधिक कुशल है:एक PHP सरणी populating: पहले सूचकांक की जांच करें?

if (!isset($array[$key])) $array[$key] = $val; 

या

$array[$key] = $val; 

दूसरा रूप जहाँ तक पठनीय कोड और अधिक वांछनीय है जाता है। हकीकत में नाम लंबे हैं और सरणी बहुआयामी है। तो पहला फॉर्म मेरे कार्यक्रम में बहुत गहराई से दिख रहा है।

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

आम तौर पर यह कोड "$ कुंजी" के समान मूल्य के साथ कई बार निष्पादित करेगा। तो ज्यादातर मामलों में $ सरणी [$ कुंजी] पहले ही सेट हो जाएगी, और जारीकर्ता() FALSE लौटाएगा।

उन लोगों के लिए स्पष्टीकरण देने के लिए जो डरते हैं कि मैं गैर-समान कोड का इलाज कर रहा हूं जैसे कि यह समान था: जहां तक ​​इस कार्यक्रम का हिस्सा है, $ वैल स्थिर है। यह रन-टाइम तक ज्ञात नहीं है, लेकिन यह प्रोग्राम में पहले सेट है और यहां नहीं बदला है। तो दोनों रूप एक ही परिणाम उत्पन्न करते हैं। और यह $ वैल्यू पाने के लिए सबसे सुविधाजनक जगह है।

उत्तर

1

तुलना की ओवरहेड जो वास्तविक हो सकती है या नहीं भी हो सकती है, ऐसा लगता है कि इसे अधिक समय लेना चाहिए।

दोनों कॉन्फ़िगरेशन में स्क्रिप्ट को चलाने का प्रदर्शन प्रदर्शन समय के लिए क्या दिखाता है?

0

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

+0

पीएचपी मैनुअल का कहना है कि "isset()" एक "भाषा निर्माण", नहीं एक समारोह है । तो मुझे उम्मीद है कि ओवरहेड वास्तव में न्यूनतम हो सकता है। मान लीजिए मुझे इसे प्रोफाइल करना होगा और देखेंगे। –

3

जारीकर्ता() सामान्य चर के साथ बहुत तेज है, लेकिन आपके पास यहां एक सरणी है। सरणी के लिए हैश-मैप एल्गोरिदम त्वरित है, लेकिन अभी भी कुछ भी करने से अधिक समय लगता है।

अब, पहला फॉर्म तेज़ हो सकता है यदि आपके पास सेट किए गए अधिक मूल्य हैं, जो कि नहीं हैं, बस इसलिए कि यह केवल हैश के बिना हैश को देखे या सेट कर रहा है। तो, यह अंतर का एक बिंदु हो सकता है: यदि आपके पास सेट की गई कुंजियों पर अधिक 'हिट' हैं, तो पहला फॉर्म चुनें, और यदि आपके पास 'मिस' है तो दूसरा चुनें।

कृपया ध्यान दें कि कोड के उन दो टुकड़े समान नहीं हैं। पहला फॉर्म कुछ कुंजी के लिए मान सेट नहीं करेगा जब यह पहले से सेट हो चुका है - यह 'ओवरराइटिंग' को रोकता है।

+0

कोड के दो टुकड़े प्रभावी रूप से समान हैं यदि $ वैल स्थिर है। मेरे उद्देश्यों के लिए यह है। इसे स्पष्ट करने के लिए मेरे प्रश्न को संपादित किया; धन्यवाद। –

+0

सुनिश्चित नहीं है कि मैं आपका उत्तर समझता हूं, हालांकि: "यदि आपके पास पहले से सेट की गई कुंजी पर अधिक 'हिट' है तो दूसरा चुनें"। क्या आप कह रहे हैं कि यदि $ सरणी [$ कुंजी] पहले से अधिक बार सेट की जाएगी, तो मुझे कॉल जारी नहीं करना चाहिए()? –

+0

@bslorence - आप सही हैं, मैंने इसे अभी तय कर दिया है। –

2

क्या आपने यह माप लिया है कि आप कितनी बार इस स्थिति में भागते हैं कि $array[$key] इसे सेट करने का प्रयास करने से पहले सेट है? मुझे लगता है कि कोई इस पर सामान्य सलाह नहीं दे सकता है, क्योंकि यदि वास्तव में बहुत से मामले हैं, तो जारीकर्ता चेक संभवतः सरणी पर अनैतिक सेट से बचकर कुछ समय बचा सकता है। हालांकि, अगर यह शायद ही कभी मामला है, तो ओवरहेड आपको धीमा कर सकता है ...। सबसे अच्छा बात यह है कि आपके वास्तविक कोड पर बेंचमार्क करना होगा।

हालांकि, ध्यान रखें कि दोनों कोड के विभिन्न परिणाम ले सकते हैं! यदि $array[$key] संयोजन के लिए $ वैल हमेशा समान नहीं होता है, तो पूर्व कोड हमेशा उस के लिए पहले $val पर मान सेट करेगा जहां बाद वाला कोड हमेशा उस संयोजन के अंतिम मान पर सेट करेगा।

(मुझे लगता है कि आपको लगता है कि के बारे में पता कर रहे हैं और $val हमेशा $array[$key] के लिए एक ही है, लेकिन कुछ नहीं हो सकता है पाठक द्वारा रोक।)

0

आप एक वास्तविक जांच की जरूरत है, तो कुंजी है देखने के लिए? एक खाली सरणी के लिए असाइनमेंट के साथ isset() बस लूप को धीमा कर देगा। और जब तक आप डेटा मैनिपुलेशन के साथ दूसरा पास नहीं करते हैं, मैं दृढ़ता से जारीकर्ता चेक के खिलाफ सलाह देता हूं। यह आबादी है, हेरफेर नहीं।

10

एक सरणी के लिए आप वास्तव में चाहते हैं: array_key_exists($key, $array)isset($array[$key]) के बजाय।

+0

जारी() वास्तव में बहुत तेज़ है। PHP ऑनलाइन मैनुअल में array_key_exists पृष्ठ पर टिप्पणियां देखें। –

+0

स्पष्ट रूप से जारी() भ्रामक हो सकता है, हालांकि, अगर यह $ array [$ key] == null: http://us3.php.net/manual/en/function.array-key-exists है तो यह गलत हो जाता है। PHP # 83500 मेरी स्थिति को प्रभावित नहीं करता है लेकिन इसके बारे में जानने योग्य है। –

+0

यदि आप इसके बारे में सोचते हैं, तो मान सेट नहीं है यदि यह शून्य के बराबर है, लेकिन सरणी कुंजी अभी भी मौजूद है। यदि आप किसी सरणी से कुछ हटा रहे हैं, तो आपको इस समस्या से बचने के लिए unset() का उपयोग करना चाहिए। – Powerlord

0

मैं पीएचपी करने के लिए एक नौसिखिया हूँ, लेकिन दोनों के संयोजन त्रिगुट ऑपरेटर

$array[$key] = !isset($array[$key]) ? $val : $array[$key]; 

एक तरह से इसके साथ जाने के लिए उस के साथ हो सकता है।

0

आप अंतर देखने के लिए PHP स्रोत कोड पर एक नज़र डाल सकते हैं। यह जांच नहीं किया कि यह PHP के बाद के संस्करणों में अलग होगा, लेकिन यह PHP3 में प्रतीत होता है कि एसोसिएटिव सरणी कार्यक्षमता php3/php3_hash.c में है।

समारोह _php3_hash_exists में, निम्न बातें किया जाता है:

  • कुंजी मिश्रित होता है
  • सही बाल्टी पाया
  • बाल्टी चला गया, जब तक सही मद पाया या नहीं

समारोह _php3_hash_add_or_update :

  • टुकड़ों में बांटा
  • बाल्टी पाया
  • चला गया, अगर
    • यदि मौजूद नहीं था अस्तित्व में अधिरोहित मौजूदा, नया एक जोड़ा

इसलिए यह सिर्फ यह तेजी से है की स्थापना प्रतीत होता है, क्योंकि केवल एक फ़ंक्शन कॉल है और यह हैशिंग और बाल्टी ढूंढने वाला व्यवसाय केवल एक बार किया जाएगा।

1

आपको उस सरणी को जांचना चाहिए, जिसमें आप जिस स्तर को सेट करने जा रहे हैं उसे शामिल नहीं करना चाहिए।

आप आप यह सुनिश्चित करें कि level2 तक मार्ग वास्तव में स्तर 3 की स्थापना करने से पहले से मौजूद है बनाना चाहिए

$anArray[ 'level1' ][ 'level2' ][ 'level3' ] = ... 

सेट करने के लिए जा रहे हैं।

$anArray[ 'level1' ][ 'level2' ] 

यदि आप नहीं करते हैं तो कोई पिल्ले वास्तव में नहीं मारे जाएंगे, लेकिन वे आपके विशेष पर्यावरण के आधार पर नाराज हो सकते हैं।

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

एक आसान तरीका यह करने के लिए नहीं है:

<?php 

function create_array_path($path, & $inArray) 
{ 
    if (! is_array($inArray)) 
    { 
     throw new Exception('The second argument is not an array!'); 
    } 
    $traversed = array(); 
    $current = &$inArray; 

    foreach($path as $subpath) 
    { 
     $traversed[] = $subpath; 
     if (! is_array($current)) 
     { 
      $current = array(); 
     } 
     if (! array_key_exists($subpath, $current)) 
     { 
      $current[ $subpath ] = ''; 
     } 
     $current = &$current[ $subpath ]; 
    } 
} 


$myArray = array(); 

create_array_path(array('level1', 'level2', 'level3'), $myArray); 

print_r($myArray); 

?> 

हो जाएगा ताकि उत्पादन:

Array 
    (
     [level1] => Array 
      (
       [level2] => Array 
        (
         [level3] => 
        ) 

      ) 

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