2011-05-23 11 views
9

मैं एक प्राथमिक कुंजी मैं बनाने रहा हूँ पर टक्कर के खिलाफ परीक्षण करने के लिए निम्नलिखित सरल कोड है के लिए खोज करने के लिए सरणी Fatest रास्ता:PHP in_array() भयानक प्रदर्शन। मूल्य

$machine_ids = array(); 

for($i = 0; $i < 100000; $i++) { 
    //Generate machine id returns a 15 character alphanumeric string 
    $mid = Functions::generate_machine_id(); 

    if(in_array($mid, $machine_ids)) { 
     die("Collision!"); 
    } else { 
     $machine_ids[] = $mid; 
    } 
} 

die("Success!"); 

किसी भी विचार क्यों इस चलाने के लिए कई मिनट ले जा रहा है? वैसे भी इसे तेज करने के लिए?

+5

आप प्रोफाइल है कि 'in_array' है है होना चाहिए करने के लिए अपने कोड refactor अपराधी और नहीं 'कार्य :: gener_machine_id() '? – deceze

+0

आपके पास 'Functions :: gener_machine_id' के लिए कोड है? – cHao

उत्तर

11
for($i = 0; $i < 100000; $i++) 
{ 
    //Generate machine id returns a 15 character alphanumeric string 
    $mid = Functions::generate_machine_id(); 
    if (isset($machine_ids[$mid])) 
    { 
    die("Collision!"); 
    } 
    $machine_ids[$mid] = true; 
} 
11

इसके लिए, $mid कुंजी के रूप में उपयोग करें, और डमी मूल्य मान के रूप में उपयोग करें। विशेष रूप से,

if(in_array($mid, $machine_ids)) { 
    die("Collision!"); 
} else { 
    $machine_ids[] = $mid; 
} 

उपयोग

if(isset($machine_ids[$mid])) { 
    die("Collision!"); 
} else { 
    $machine_ids[$mid] = 1; 
} 

अंत में करने के बजाय आप सरणी आप मूल रूप से array_keys($machine_ids) साथ चाहता था निकाल सकते हैं।

यह बहुत तेज़ होना चाहिए। यदि यह अभी भी धीमा है, तो आपका Functions::generate_machine_id() धीमा है।

टिप्पणियों के अनुसार isset जोड़ने के लिए संपादित किया गया।

+2

मुझे इसे मारो। :) हालांकि आपको 'isset ($ machine_ids [$ mid]) का उपयोग करना चाहिए। – deceze

+0

धोखे से सहमत हैं, और मेरा मानना ​​है कि 'अगर ($ machine_ids [$ mid])' झूठी वापसी होगी (वास्तव में टक्कर नहीं) यदि मान पूर्णांक 0, खाली स्ट्रिंग, न्यूल इत्यादि है। किसी भी मामले में 'isset()' जाने का रास्ता है। हालांकि, मैंने अभी देखा ओपी ने कहा कि यह हमेशा 15 चार अल्फानम होगा। –

+0

@deceze: कोई कारण? क्या बूलियन के निहित रूपांतरण के प्रदर्शन हिट की तुलना में 'जारीकर्ता' का प्रदर्शन हिट है? या यह सैद्धांतिक है - क्योंकि PHP '0' में भी झूठा है, जो 'जारीकर्ता' से अलग होगा? (इस मामले में, हमारे पास खाली और खाली हैं, इसलिए यह सुरक्षित है) – Amadan

3

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

यदि आपको सदस्यता परीक्षणों का पूरा समूह करने की आवश्यकता है, जैसा कि यहां है, तो आपको एक अलग डेटा संरचना का उपयोग करना चाहिए जो हे (1) सदस्यता परीक्षणों का समर्थन करता है, जैसे हैश।

1

इतना है कि यह एक जुड़े सरणी का उपयोग करता है मशीन आईडी पकड़ और isset का उपयोग

if(isset($machine_id[$mid])) die("Collision"); 

$machine_ids[$mid] = $mid; 

जाँच करने के लिए isset का उपयोग करते हुए तेजी से

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