PHP में बनाम फॉरएच का प्रदर्शन


134

सबसे पहले, मैं समझता हूं कि 90% अनुप्रयोगों में प्रदर्शन अंतर पूरी तरह से अप्रासंगिक है, लेकिन मुझे सिर्फ यह जानना होगा कि कौन सा निर्माण तेजी से हो रहा है। वह और ...

वर्तमान में नेट पर उन पर उपलब्ध जानकारी भ्रमित कर रही है। बहुत से लोग कहते हैं कि फॉर्च्यूनर खराब है, लेकिन तकनीकी रूप से इसे तेज होना चाहिए क्योंकि यह इटेरेटर्स का उपयोग करके एक सरणी ट्रैवर्सल लिखने को सरल बनाने के लिए माना जाता है। Iterators, जो फिर से तेज़ होने का अनुमान लगा रहे हैं, लेकिन PHP में भी स्पष्ट रूप से धीमी गति से मृत हैं (या यह एक PHP चीज नहीं है?)। मैं सरणी फ़ंक्शन के बारे में बात कर रहा हूं: अगले () prev () रीसेट () आदि अच्छी तरह से, अगर वे फ़ंक्शन भी हैं और उन PHP भाषा सुविधाओं में से एक नहीं है जो फ़ंक्शन की तरह दिखते हैं।

इसे थोड़ा कम करने के लिए : मैं 1 से अधिक (कुछ भी नकारात्मक कदम नहीं है, यानी उलटा चलना) के चरणों में ट्रेवर्सिंग ट्रे में दिलचस्प नहीं हूं। मैं मनमाने ढंग से और केवल 0 से लंबाई तक के ट्रैवर्सल में दिलचस्पी नहीं ले रहा हूं। मैं एक नियमित आधार पर 1000 से अधिक कुंजी के साथ सरणियों में हेरफेर नहीं देखता, लेकिन मैं एक सरणी को एक आवेदन के तर्क में कई बार फंसता हुआ देखता हूं! संचालन के लिए भी, मोटे तौर पर केवल स्ट्रिंग हेरफेर और गूंज।

यहाँ कुछ संदर्भ साइटें हैं:
http://www.phpbench.com/
http://www.php.lt/benchmark/phpbench.php

मैं हर जगह सुनता हूं:

  • foreachधीमा है, और इस प्रकार for/ whileतेज है
  • PHP foreachउस सरणी को कॉपी करती है जिस पर वह पुनरावृति करता है; इसे तेज़ करने के लिए आपको संदर्भों का उपयोग करने की आवश्यकता है
  • इस तरह कोड: एक से अधिक तेज है$key = array_keys($aHash); $size = sizeOf($key);
    for ($i=0; $i < $size; $i++)
    foreach

यहाँ मेरी समस्या है। मैंने यह टेस्ट स्क्रिप्ट लिखी है: http://pastebin.com/1ZgK07US और कोई फर्क नहीं पड़ता कि मैं कितनी बार स्क्रिप्ट चलाता हूं, मुझे कुछ इस तरह मिलता है:

foreach 1.1438131332397
foreach (using reference) 1.2919359207153
for 1.4262869358063
foreach (hash table) 1.5696921348572
for (hash table) 2.4778981208801

संक्षेप में:

  • foreachforeachसंदर्भ से तेज है
  • foreach से तेज है for
  • foreachforएक हैश तालिका के लिए की तुलना में तेजी है

क्या कोई समझा सकता है?

  1. क्या मुझसे कुछ गलत हो रही है?
  2. क्या PHP foreach संदर्भ चीज़ वास्तव में एक अंतर बना रही है? मेरा मतलब है कि यदि आप संदर्भ से गुजरते हैं तो इसे कॉपी क्यों नहीं करेंगे?
  3. फॉर्च्यूमेंट स्टेटमेंट के लिए समान इटरेटर कोड क्या है; मैंने नेट पर कुछ देखा है, लेकिन हर बार जब मैं उनका परीक्षण करता हूं तो समय समाप्त हो जाता है; मैंने कुछ सरल पुनरावृत्तियों के निर्माण का भी परीक्षण किया है, लेकिन कभी भी अच्छे परिणाम प्राप्त करने के लिए प्रतीत नहीं होता है - क्या PHP में सरणी पुनरावृत्तियों सिर्फ भयानक हैं?
  4. वहाँ तेजी से तरीके / तरीके / निर्माण हालांकि यह करने के लिए एक सरणी के अलावा / FOREACH (और WHILE) हैं?

PHP संस्करण 5.3.0


संपादित करें: उत्तर यहां के लोगों की मदद से मैं सभी प्रश्नों के उत्तर एक साथ दे पा रहा था। मैं उन्हें यहाँ संक्षेप में बताऊंगा:

  1. "क्या मुझसे कुछ गलत हो रही है?" सर्वसम्मति से प्रतीत होता है: हाँ, मैं बेंचमार्क में प्रतिध्वनि का उपयोग नहीं कर सकता। व्यक्तिगत रूप से, मैं अभी भी यह नहीं देख पा रहा हूं कि निष्पादन के यादृच्छिक समय के साथ इको कुछ कार्य कैसे होता है या कोई अन्य फ़ंक्शन किसी भी तरह से कैसे भिन्न होता है - और उस लिपि की क्षमता केवल हर चीज की तुलना में बेहतर फॉर्च्यूनर के सटीक समान परिणाम उत्पन्न करने के लिए कठिन है हालांकि समझाने के लिए "आप इको का उपयोग कर रहे हैं" (अच्छी तरह से मुझे क्या उपयोग करना चाहिए था)। हालांकि, मैं मानता हूं कि परीक्षण कुछ बेहतर होना चाहिए; हालांकि एक आदर्श समझौता दिमाग में नहीं आता है।
  2. "क्या PHP foreach संदर्भ चीज़ वास्तव में एक अंतर बना रही है? मेरा मतलब है कि यदि आप संदर्भ से गुजरते हैं तो इसे कॉपी क्यों नहीं करेंगे?" ircmaxell से पता चलता है कि हाँ यह है, आगे के परीक्षण से साबित होता है कि ज्यादातर मामलों में संदर्भ तेज होना चाहिए - हालांकि कोड के ऊपर मेरे स्निपेट को देखते हुए, निश्चित रूप से सभी का मतलब यह नहीं है। मैं स्वीकार करता हूं कि इस तरह के स्तर पर परेशान करने के लिए मुद्दा शायद गैर-सहज है और इसके लिए कुछ चरम की आवश्यकता होगी जैसे कि वास्तव में यह निर्धारित करने के लिए विघटित करना जो प्रत्येक स्थिति के लिए बेहतर है।
  3. "फॉर्च्यूमेंट स्टेटमेंट के लिए समान इटरेटर कोड क्या है? मैंने नेट पर कुछ देखा है, लेकिन हर बार जब मैं उनका परीक्षण करता हूं तो समय समाप्त हो जाता है; मैंने कुछ सरल इटरेटर निर्माणों का भी परीक्षण किया है लेकिन कभी भी अच्छे परिणाम प्राप्त नहीं होते हैं। - क्या PHP में सरणी पुनरावृत्तियाँ केवल भयानक हैं? " ircmaxell ने उत्तर दिया bellow; हालांकि कोड केवल PHP संस्करण> = 5 के लिए मान्य हो सकता है
  4. "वहाँ तेजी से तरीके / तरीके / निर्माण करने के लिए हालांकि एक सरणी के अलावा / FOREACH (और WHILE)?" धन्यवाद उत्तर के लिए गॉर्डन जाओ। PHP5 में नए डेटा प्रकारों का उपयोग करना या तो एक प्रदर्शन को बढ़ावा देना या मेमोरी बूस्ट देना चाहिए (या तो आपकी स्थिति के आधार पर वांछनीय हो सकता है)। हालांकि गति के नए प्रकार के बहुत से सरणी सरणी () से बेहतर नहीं लगते हैं, लेकिन शानदार और स्प्लोबजेस्टस्टोरेज काफी तेजी से प्रतीत होते हैं। गॉर्डन द्वारा प्रदान की गई लिंक: http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/

आप सभी को धन्यवाद जिन्होंने मदद करने की कोशिश की।

मैं संभवतः किसी भी सरल ट्रैवर्सल के लिए फॉरच (गैर-संदर्भ संस्करण) से चिपके रहूंगा।


7
बेंचमार्किंग का नियम 2.71: बेंचमार्क की प्रतिध्वनि न करें।
Mchl

1
संदर्भ के साथ foreach को संदर्भ के साथ चिह्नित किया जाना चाहिए। आपका वहां त्रुटिपूर्ण निष्कर्ष है। एक संदर्भ का कोई भी उपयोग स्पष्ट रूप से एक संदर्भ के बिना धीमी गति से होने वाला है, यहां तक ​​कि एक डू-लूप में भी।
बोकोस्का

2
चूँकि यह php 5.3 के लिए है, इसलिए आप नए Spl Data Types बनाम Arrays के परीक्षण पर भी विचार कर सकते हैं। या बस यहाँ देखें: matthewturland.com/2010/05/20/new-spl-features-in-php-5-3
गॉर्डन

@ Mchl: मैंने इसे कुछ बार चलाया, और एक ही परिणाम मिला - यदि इको बेंचमार्क को भ्रष्ट करता है तो क्या मुझे पूरी तरह से यादृच्छिक परिणाम नहीं मिलना चाहिए? मैं भी कुछ करना चाहता हूँ और यह इतना गूंज वास्तव में मेरे लिए वास्तव में महत्वपूर्ण है उत्पादन करना चाहते हैं; अगर इको इज़ करने के बाद फॉरच तेज होता है तो कोड का एक बड़ा हिस्सा है जहां मुझे फ़ॉरच का उपयोग करना चाहिए। @ अभी भी: जो मैं सुन रहा हूं, वह मूल रूप से "संदर्भ में फॉरचेक बनाता है (हमेशा), हमेशा संदर्भ के साथ लिखें" की तर्ज पर है, यही कारण है कि मैंने इस तरह का परीक्षण किया - मैं वास्तव में अन्य संदर्भ छोरों की तुलना में दिलचस्पी नहीं रखता हूं
11

2
इन खाली प्रश्नों को स्वाभाविक रूप से प्रतिबंधित किया जाना चाहिए। साथ ही उस धोखेबाज phpbench साइट
आपका कॉमन सेंस

जवाबों:


110

मेरी निजी राय यह है कि संदर्भ में जो समझ में आता है उसका उपयोग करें। व्यक्तिगत रूप से मैं लगभग forसरणी ट्रैवर्सल के लिए उपयोग नहीं करता हूं । मैं इसे अन्य प्रकार के पुनरावृत्ति के लिए उपयोग करता हूं, लेकिन foreachअभी भी बहुत आसान है ... अधिकांश मामलों में समय का अंतर न्यूनतम होने जा रहा है।

देखने के लिए बड़ी बात यह है:

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

यह एक महंगा लूप है, क्योंकि यह हर एक पुनरावृत्ति पर गिनती कहता है। जब तक आप ऐसा नहीं कर रहे हैं, मुझे नहीं लगता कि यह वास्तव में मायने रखता है ...

संदर्भ के अंतर के रूप में, PHP कॉपी-ऑन-राइट का उपयोग करता है, इसलिए यदि आप सरणी पर नहीं लिखते हैं, तो लूप करते समय अपेक्षाकृत कम ओवरहेड होगा। हालाँकि, यदि आप सरणी को सरणी के भीतर संशोधित करना शुरू करते हैं, तो आप उनके बीच अंतर देखना शुरू कर देंगे (क्योंकि किसी को पूरे सरणी की प्रतिलिपि बनाने की आवश्यकता होगी, और संदर्भ केवल इनलाइन को संशोधित कर सकता है ...)

पुनरावृत्तियों के लिए, foreachइसके बराबर है:

$it->rewind();
while ($it->valid()) {
    $key = $it->key();     // If using the $key => $value syntax
    $value = $it->current();

    // Contents of loop in here

    $it->next();
}

जहाँ तक पुनरावृति के तेज़ तरीके होने की बात है, यह वास्तव में समस्या पर निर्भर करता है। लेकिन मुझे वास्तव में पूछने की आवश्यकता है, क्यों? मैं समझता हूं कि चीजों को अधिक कुशल बनाना चाहते हैं, लेकिन मुझे लगता है कि आप अपना समय सूक्ष्म अनुकूलन के लिए बर्बाद कर रहे हैं। याद रखें, Premature Optimization Is The Root Of All Evil...

संपादित करें: टिप्पणी के आधार पर, मैंने एक त्वरित बेंचमार्क चलाने का निर्णय लिया ...

$a = array();
for ($i = 0; $i < 10000; $i++) {
    $a[] = $i;
}

$start = microtime(true);
foreach ($a as $k => $v) {
    $a[$k] = $v + 1;
}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => &$v) {
    $v = $v + 1;
}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => $v) {}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => &$v) {}    
echo "Completed in ", microtime(true) - $start, " Seconds\n";

और परिणाम:

Completed in 0.0073502063751221 Seconds
Completed in 0.0019769668579102 Seconds
Completed in 0.0011849403381348 Seconds
Completed in 0.00111985206604 Seconds

इसलिए यदि आप लूप में सरणी को संशोधित कर रहे हैं, तो यह संदर्भों का उपयोग करने के लिए कई गुना तेज़ है ...

और सिर्फ संदर्भ के लिए ओवरहेड वास्तव में सरणी की प्रतिलिपि बनाने से कम है (यह 5.3.2 पर है) ... इसलिए यह प्रतीत होता है (5.3.2 कम से कम) के रूप में यदि संदर्भ काफी तेज हैं ...


1
क्या आपका मतलब नहीं है "[नियोजित नहीं] अनुकूलन सभी बुराई की जड़ है"? ;) अच्छी बात यह है कि वे सभी एक ही काम करते हैं, इसलिए यह इतना अनुकूलन नहीं है जितना कि यह है: "जो अपनाने के लिए बेहतर मानक तरीका है।" इसके अलावा कुछ और प्रश्न अनुत्तरित हैं: आप कहते हैं क्योंकि इसे कॉपी नहीं करना है, लेकिन संदर्भ का उपयोग एक उपरि भी नहीं है? मेरे प्रश्न में अभी भी समझ में नहीं आने वाली टिप्पणी आपकी मान्यताओं से असहमत है। इसके अलावा, कोड संदर्भ के लिए धीमा क्यों है। क्या किसी भी सरणी () को किसी ऑब्जेक्ट (जैसे। SplFixedArray) में परिवर्तित करने के लिए 5.3.0 में फॉरेक्स बदल गया?
srcspider

@srcspider: संदर्भ के साथ बेंचमार्क कोड और परिणाम दिखाने वाले संपादित उत्तर वास्तव में गैर-संदर्भों की तुलना में बहुत तेज़ हैं ...
ircmaxell

1
@srcspider "the better standard way to adopt." प्रदर्शन केवल यह चुनने के लिए मापदंड नहीं है कि क्या अपनाया जाए। विशेष रूप से इस तरह के एक दूर के मामले में। सच कहूं, तो आप अपना समय बर्बाद कर रहे हैं
आपका कॉमन सेंस

@Col। Shrapnel I सहमत 100%। इस विशेष मामले में बड़े अंतर से पठनीयता और स्थिरता ट्रम्प का प्रदर्शन ... मैं एक मानक को चुनने और इसके साथ चिपके रहने के बारे में सहमत हूं, लेकिन आधार उस मानक पर अन्य --more महत्वपूर्ण-- कारक ...
ircmaxell

@ सर्कमैक्सेल: आपकी स्क्रिप्ट को जल्दी से चलाना आपकी बात को सही साबित करता है, लेकिन मैं इसे थोड़ा आगे देखना चाहता हूं; मैं अपने मूल प्रश्न को नए 5.3 फीचर सहित कुछ और टेस्टस्टो के साथ संपादित कर सकता हूं। @Col। Shrapnel: के लिए लगभग सार्वभौमिक प्रोग्रामिंग-किंडरगार्डन स्तर है, FOREACH सरल वाक्यविन्यास है। जहाँ तक पठनीयता है, वे बराबर जमीन पर लगते हैं। यह सब इतना निम्न स्तर है मुझे नहीं लगता कि रखरखाव एक मुद्दा है जैसा कि कुछ उच्च स्तर के पैटर्न के लिए होगा। और मुझे नहीं लगता कि मैं अपना समय बर्बाद कर रहा हूं क्योंकि यह "बुनियादी निर्माण" बहुत सारे कोड के लिए होगा जो मैं लिखूंगा। :)
srcspider 14

54

मुझे यकीन नहीं है कि यह बहुत आश्चर्यजनक है। अधिकांश लोग जो PHP में कोड करते हैं, वे अच्छी तरह से वाकिफ नहीं हैं कि PHP वास्तव में नंगे धातु पर क्या कर रहा है। मैं कुछ चीजें बताऊंगा, जो ज्यादातर समय सच होंगी:

  1. यदि आप चर को संशोधित नहीं कर रहे हैं, तो उप-मान PHP में तेज है। ऐसा इसलिए है क्योंकि यह किसी भी तरह से संदर्भित संदर्भ है और उप-मूल्य इसे करने के लिए कम देता है। यह दूसरे को जानता है कि आप उस ZVAL (अधिकांश प्रकारों के लिए PHP की आंतरिक डेटा संरचना) को संशोधित करते हैं, इसे सीधे तरीके से तोड़ना होगा (इसे कॉपी करें और अन्य ZVAL के बारे में भूल जाएं)। लेकिन आप इसे कभी संशोधित नहीं करते हैं, इसलिए इससे कोई फर्क नहीं पड़ता। संदर्भ बनाता है कि अधिक बहीखाता पद्धति के साथ और अधिक जटिल है यह जानने के लिए कि आपको चर को संशोधित करने के लिए क्या करना है । इसलिए यदि आप केवल पढ़ने के लिए हैं, तो विरोधाभासी रूप से यह बेहतर नहीं है कि बाहर और साथ में। मुझे पता है, यह सहज है, लेकिन यह भी सच है।

  2. Foreach धीमा नहीं है। और सरल पुनरावृत्ति के लिए, जिस स्थिति के खिलाफ परीक्षण किया जा रहा है - "मैं इस सरणी के अंत में हूं" - मूल कोड का उपयोग करके किया जाता है, न कि PHP ऑपकोड। भले ही यह एपीसी कैश्ड ओपकोड्स हो, यह अभी भी नंगे धातु पर किए गए मूल संचालन के एक समूह की तुलना में धीमा है।

  3. लूप के लिए "के लिए" ($ i = 0; $ i <count ($ x); $ i ++) का उपयोग गिनती (), और PHP की क्षमता (या वास्तव में किसी भी व्याख्या की गई भाषा) की कमी के कारण होता है। समय चाहे कुछ भी सरणी को संशोधित करता हो। यह एक बार गिनती का मूल्यांकन करने से रोकता है।

  4. लेकिन एक बार भी आप इसे "$ c = count ($ x) के साथ ठीक कर लेते हैं; ($ i = 0; $ i <$ c; $ i ++) $ i <$ c सबसे अच्छे रूप में Zend opcodes का एक गुच्छा है। $ i ++। 100000 पुनरावृत्तियों के दौरान, यह बात कर सकता है। फ़ॉर्चो देशी स्तर पर जानता है कि क्या करना है। "PHP मैं इस सरणी के अंत में हूं" परीक्षण करने के लिए किसी भी opcodes की आवश्यकता नहीं है।

  5. पुराने स्कूल के बारे में क्या है जबकि (सूची ("सामान? खैर, प्रत्येक का उपयोग करके), (), वर्तमान (), आदि सभी कम से कम 1 फ़ंक्शन कॉल को शामिल करने जा रहे हैं, जो धीमा नहीं है, लेकिन स्वतंत्र नहीं है। हां, उन। PHP फिर opcodes हैं! इसलिए जबकि + सूची + प्रत्येक की लागत भी है।

इन कारणों से साधारण पुनरावृत्ति के लिए सबसे अच्छा विकल्प है।

और मत भूलो, यह पढ़ना भी सबसे आसान है, इसलिए यह जीत है।


यह ठीक वही स्पष्टीकरण है जिसकी मुझे तलाश थी, धन्यवाद।
10

यह उत्तर वास्तव में चिह्नित उत्तर का एक सारांश या सारांश होना चाहिए। मुझे खुशी है कि मैंने इसे पढ़ा, अच्छा काम किया।
११16 --16

30

बेंचमार्क (विशेष रूप से phpbench.com) के लिए देखने वाली एक बात यह है कि भले ही संख्या ध्वनि हो, परीक्षण नहीं हैं। Phpbench.com पर परीक्षणों का एक बहुत कुछ कर रहे हैं और तुच्छ और दुरुपयोग कर रहे हैं PHP सरणी को देखने के लिए बेंचमार्क तिरछा करने के लिए या एक सरणी पर पुनरावृत्ति के मामले में वास्तव में वास्तविक दुनिया के मामलों में इसका परीक्षण नहीं करता है (कोई भी व्यक्ति इसके लिए खाली नहीं है) छोरों)। मैंने अपने स्वयं के बेंचमार्क किए हैं जो मैंने पाया है कि वे वास्तविक दुनिया के परिणामों के प्रति काफी चिंतनशील हैं और वे हमेशा भाषा के मूल पुनरावृति वाक्य-विन्यास foreachको शीर्ष पर (आश्चर्य, आश्चर्य) दिखाते हैं ।

//make a nicely random array
$aHash1 = range( 0, 999999 );
$aHash2 = range( 0, 999999 );
shuffle( $aHash1 );
shuffle( $aHash2 );
$aHash = array_combine( $aHash1, $aHash2 );


$start1 = microtime(true);
foreach($aHash as $key=>$val) $aHash[$key]++;
$end1 = microtime(true);

$start2 = microtime(true);
while(list($key) = each($aHash)) $aHash[$key]++;
$end2 = microtime(true);


$start3 = microtime(true);
$key = array_keys($aHash);
$size = sizeOf($key);
for ($i=0; $i<$size; $i++) $aHash[$key[$i]]++;
$end3 = microtime(true);

$start4 = microtime(true);
foreach($aHash as &$val) $val++;
$end4 = microtime(true);

echo "foreach ".($end1 - $start1)."\n"; //foreach 0.947947025299
echo "while ".($end2 - $start2)."\n"; //while 0.847212076187
echo "for ".($end3 - $start3)."\n"; //for 0.439476966858
echo "foreach ref ".($end4 - $start4)."\n"; //foreach ref 0.0886030197144

//For these tests we MUST do an array lookup,
//since that is normally the *point* of iteration
//i'm also calling noop on it so that PHP doesn't
//optimize out the loopup.
function noop( $value ) {}

//Create an array of increasing indexes, w/ random values
$bHash = range( 0, 999999 );
shuffle( $bHash );

$bstart1 = microtime(true);
for($i = 0; $i < 1000000; ++$i) noop( $bHash[$i] );
$bend1 = microtime(true);

$bstart2 = microtime(true);
$i = 0; while($i < 1000000) { noop( $bHash[$i] ); ++$i; }
$bend2 = microtime(true);


$bstart3 = microtime(true);
foreach( $bHash as $value ) { noop( $value ); }
$bend3 = microtime(true);

echo "for ".($bend1 - $bstart1)."\n"; //for 0.397135972977
echo "while ".($bend2 - $bstart2)."\n"; //while 0.364789962769
echo "foreach ".($bend3 - $bstart3)."\n"; //foreach 0.346374034882

3

यह 2020 है और सामान php 7.4 और opcache के साथ विकसित हुआ था

यहाँ ओपी ^ बेंचमार्क है, यूनिक्स सीएलआई के रूप में चलाया जाता है इको और html भागों के बिना ।

टेस्ट नियमित रूप से कंप्यूटर पर स्थानीय रूप से चलाया जाता है।

php -v

PHP 7.4.6 (cli) (built: May 14 2020 10:02:44) ( NTS )

संशोधित बेंचमार्क स्क्रिप्ट:

<?php 
 ## preperations; just a simple environment state

  $test_iterations = 100;
  $test_arr_size = 1000;

  // a shared function that makes use of the loop; this should
  // ensure no funny business is happening to fool the test
  function test($input)
  {
    //echo '<!-- '.trim($input).' -->';
  }

  // for each test we create a array this should avoid any of the
  // arrays internal representation or optimizations from getting
  // in the way.

  // normal array
  $test_arr1 = array();
  $test_arr2 = array();
  $test_arr3 = array();
  // hash tables
  $test_arr4 = array();
  $test_arr5 = array();

  for ($i = 0; $i < $test_arr_size; ++$i)
  {
    mt_srand();
    $hash = md5(mt_rand());
    $key = substr($hash, 0, 5).$i;

    $test_arr1[$i] = $test_arr2[$i] = $test_arr3[$i] = $test_arr4[$key] = $test_arr5[$key]
      = $hash;
  }

  ## foreach

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    foreach ($test_arr1 as $k => $v)
    {
      test($v);
    }
  }
  echo 'foreach '.(microtime(true) - $start)."\n";  

  ## foreach (using reference)

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    foreach ($test_arr2 as &$value)
    {
      test($value);
    }
  }
  echo 'foreach (using reference) '.(microtime(true) - $start)."\n";

  ## for

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    $size = count($test_arr3);
    for ($i = 0; $i < $size; ++$i)
    {
      test($test_arr3[$i]);
    }
  }
  echo 'for '.(microtime(true) - $start)."\n";  

  ## foreach (hash table)

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    foreach ($test_arr4 as $k => $v)
    {
      test($v);
    }
  }
  echo 'foreach (hash table) '.(microtime(true) - $start)."\n";

  ## for (hash table)

  $start = microtime(true);
  for ($j = 0; $j < $test_iterations; ++$j)
  {
    $keys = array_keys($test_arr5);
    $size = sizeOf($test_arr5);
    for ($i = 0; $i < $size; ++$i)
    {
      test($test_arr5[$keys[$i]]);
    }
  }
  echo 'for (hash table) '.(microtime(true) - $start)."\n";

आउटपुट:

foreach 0.0032877922058105
foreach (using reference) 0.0029420852661133
for 0.0025191307067871
foreach (hash table) 0.0035080909729004
for (hash table) 0.0061779022216797

जैसा कि आप देख सकते हैं कि विकास पागल है, लगभग 560 समय तेजी से 2012 की तुलना में गुना है।

मेरी मशीनों और सर्वरों पर, मेरे कई प्रयोगों के बाद, लूप के लिए मूल बातें सबसे तेज हैं। यह नेस्टेड लूप ( $ i $ j $ k) का उपयोग करके और भी स्पष्ट है ..)

यह उपयोग में सबसे अधिक लचीला है, और मेरे विचार से बेहतर पठनीयता है।


0

मुझे लगता है कि मुझे यकीन नहीं है: forलूप दो मानों की जाँच और वृद्धि के लिए ऑपरेशन करता है। foreachमेमोरी में डेटा लोड करता है तो यह हर मान को पुनरावृत्त करेगा।


7
हर कोई एक राय है, लोग जवाब खोजने के लिए स्टैक ओवरफ्लो में आते हैं। यदि आप निश्चित नहीं हैं कि आप क्या कहते हैं, तो सोर्स कोड, डॉक्यूमेंटेशन, गूगल सर्च आदि करें।
सेबस्टियन एफ।

चूंकि प्रदर्शन अनुसंधान और परीक्षण पर आधारित है, इसलिए आपको कुछ सबूतों के साथ सामने आना चाहिए। कृपया तदनुसार अपने संदर्भ प्रदान करें। उम्मीद है कि आप अपने उत्तर में सुधार कर सकते हैं।
मारवान सलीम

मुझे लगता है कि यह सर्वर के वास्तविक लोड पर भी निर्भर करता है और आप लूप में क्या करना चाहते हैं। मुझे लगता है कि यह सर्वर के वास्तविक लोड पर भी निर्भर करता है और आप लूप में क्या करना चाहते हैं। मैं यह जानना चाहता था कि क्या गिने हुए सरणी से अधिक पुनरावृत्ति करना चाहिए, मुझे फ़ॉरच - या फॉर-लूप का बेहतर उपयोग करना चाहिए, इसलिए मैंने PHP 7.4 के साथ sandbox.onlinephpfunctions.com पर एक बेंचमार्क चलाया । मैं एक ही स्क्रिप्ट को कई बार दोहराता हूं और हर रन मुझे अलग परिणाम देता है। एक बार फॉर-लूप तेजी से एक बार फॉर्च-लूप और दूसरी बार वे बराबर थे।
अलेक्जेंडर बेहलिंग ने
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.