سؤال

يتعلق الأمر بـ PHP ولكن ليس لدي شك في أن العديد من التعليقات نفسها ستنطبق على اللغات الأخرى.

ببساطة، ما هي الاختلافات في أنواع الحلقات المختلفة لـ PHP؟هل أحدهما أسرع/أفضل من الآخرين أم يجب أن أضعه ببساطة في الحلقة الأكثر قابلية للقراءة؟

for ($i = 0; $i < 10; $i++)
{
    # code...
}


foreach ($array as $index => $value)
{
    # code...
}


do
{
    # code...
}
while ($flag == false);
هل كانت مفيدة؟

المحلول

حلقات For و while هي حلقات شرطية للدخول.يقومون بتقييم الحالة أولاً، لذلك لن يتم تشغيل كتلة البيان المرتبطة بالحلقة ولو مرة واحدة في حالة فشل الشرط في استيفاءه

سيتم تشغيل البيانات الموجودة داخل كتلة حلقة for هذه 10 مرات، وستكون قيمة $i من 0 إلى 9؛

for ($i = 0; $i < 10; $i++)
{
        # code...
}

نفس الشيء يتم مع حلقة while:

$i = 0;
while ($i < 10)
{
    # code...
    $i++
}

حلقة Do-while هي حلقة شرط الخروج.إنه مضمون للتنفيذ مرة واحدة، ثم سيتم تقييم الحالة قبل تكرار الكتلة

do
{
        # code...
}
while ($flag == false);

يتم استخدام foreach للوصول إلى عناصر المصفوفة من البداية إلى النهاية.في بداية حلقة foreach، يتم تعيين المؤشر الداخلي للمصفوفة على العنصر الأول من المصفوفة، وفي الخطوة التالية يتم تعيينه على العنصر الثاني من المصفوفة، وهكذا حتى انتهاء المصفوفة.في كتلة الحلقة، تتوفر قيمة عنصر الصفيف الحالي كقيمة $ ومفتاح العنصر الحالي متاح كـ $index.

foreach ($array as $index => $value)
{
        # code...
}

يمكنك أن تفعل الشيء نفسه مع حلقة while، مثل هذا

while (current($array))
{
    $index = key($array);  // to get key of the current element
    $value = $array[$index]; // to get value of current element

    # code ...  

    next($array);   // advance the internal array pointer of $array
}

و اخيرا: دليل PHP هو صديقك :)

نصائح أخرى

هذا هو CS101، ولكن بما أنه لم يذكره أحد، بينما تقوم الحلقات بتقييم حالتها قبل كتلة التعليمات البرمجية، ويتم تقييمها بعد كتلة التعليمات البرمجية، لذلك يتم ضمان حلقات do-while دائمًا لتشغيل كتلة التعليمات البرمجية الخاصة بها مرة واحدة على الأقل. بغض النظر عن الحالة.

@بريندان:

المقالة التي استشهدت بها قديمة جدًا والمعلومات خاطئة تمامًا.وخاصة النقطة الأخيرة (استخدام for بدلاً من foreach) مضلل ولم يعد التبرير المقدم في المقالة ينطبق على الإصدارات الحديثة من .NET.

في حين أنه صحيح أن IEnumerator يستخدم المكالمات الافتراضية، هذه يستطيع في الواقع تكون مضمنة بواسطة مترجم حديث.علاوة على ذلك، أصبح .NET يعرف الآن الأدوية العامة والعدادات المكتوبة بقوة.

هناك الكثير من اختبارات الأداء التي تثبت ذلك بشكل قاطع for عموما ليست أسرع من foreach. هنا مثال.

أستخدم الحلقة الأولى عند التكرار عبر مصفوفة تقليدية (مفهرسة؟) وحلقة foreach عند التعامل مع مصفوفة ترابطية.يبدو الأمر طبيعيًا ويساعد في تدفق التعليمات البرمجية ويكون أكثر قابلية للقراءة، في رأيي.أما بالنسبة إلى حلقات do... while، فأنا أستخدمها عندما يتعين علي القيام بأكثر من مجرد التنقل عبر مصفوفة.

لست متأكدًا من أي فوائد في الأداء.

الأداء ليس أفضل بكثير في كلتا الحالتين.بينما يكون مفيدًا للمهام الأكثر تعقيدًا من التكرار، لكن for و while متكافئة وظيفيا.

Foreach جميل ولكن فيه تنبيه مهم:أنت لا يمكن تعديل العدد الذي تكرره.لذلك لا داعي لإزالة أو إضافة أو استبدال الإدخالات فيه.يعد تعديل الإدخالات (مثل تغيير خصائصها) أمرًا جيدًا بالطبع.

باستخدام حلقة foreach، يتم إنشاء نسخة من المصفوفة الأصلية في الذاكرة لاستخدامها في الداخل.يجب ألا تستخدمها في الهياكل الكبيرة؛حلقة for البسيطة هي الخيار الأفضل.يمكنك استخدام حلقة while بشكل أكثر كفاءة على بنية كبيرة غير مفهرسة رقميًا مثل هذا:

while(list($key, $value) = each($array)) {

لكن هذا النهج قبيح بشكل خاص بالنسبة لهيكل صغير بسيط.

تعد حلقات while أكثر ملاءمة للتكرار عبر التدفقات، أو كما في المثال التالي الذي تراه كثيرًا في PHP:

while ($row = mysql_fetch_array($result)) {

في جميع الأوقات تقريبًا، تكون الحلقات المختلفة قابلة للتبديل، وسيعود الأمر إما إلى أ) الكفاءة، أو ب) الوضوح.

إذا كنت تعرف مقايضات الكفاءة للأنواع المختلفة من الحلقات، فنعم للإجابة على سؤالك الأصلي:استخدم الشخص الذي يبدو أكثر نظافة.

يخدم كل بناء حلقات غرضًا مختلفًا.

for - يتم استخدامه للتكرار لعدد محدد من التكرارات.

foreach - يُستخدم هذا للتنقل عبر كافة القيم الموجودة في المجموعة.

while - يتم استخدامه للتكرار حتى تستوفي الشرط.

من بين الثلاثة، من المرجح أن توفر كلمة "while" أفضل أداء في معظم المواقف.بالطبع، إذا قمت بشيء مثل ما يلي، فأنت تقوم بشكل أساسي بإعادة كتابة الحلقة "for" (والتي تكون أكثر أداءً قليلاً في C#).

$count = 0;
do
{
   ...
   $count++;
}
while ($count < 10);  

ولكل منها أغراض أساسية مختلفة، ولكن يمكن أيضًا استخدامها بنفس الطريقة إلى حد ما.يعتمد الأمر تمامًا على المشكلة المحددة التي تحاول حلها.

باستخدام حلقة foreach، يتم إنشاء نسخة من المصفوفة الأصلية في الذاكرة لاستخدامها في الداخل.

Foreach جميل، ولكن لديه تحذير واحد مهم:لا يمكنك تعديل العدد الذي تقوم بتكراره.

لن يمثل كلا الأمرين مشكلة إذا مررت بالمرجع بدلاً من القيمة:

 foreach ($array as &$value) {

أعتقد أن هذا مسموح به منذ PHP 5.

عند الوصول إلى عناصر المصفوفة، من أجل الوضوح، سأستخدم foreach كلما أمكن ذلك، واستخدم for فقط إذا كنت بحاجة إلى قيم الفهرس الفعلية (على سبيل المثال، نفس الفهرس في صفائف متعددة).وهذا أيضًا يقلل من احتمال حدوث أخطاء مطبعية نظرًا لأن حلقات for تجعل هذا الأمر سهلاً للغاية.بشكل عام، PHP قد لا يكون المكان المناسب للقلق كثيرًا بشأن الأداء.وأخيرًا وليس آخرًا، من أجل أن يكون لدينا (أو ينبغي أن يكون لدينا؛أنا لست PHP-er) في نفس وقت Big-O (O(n)) لذلك من المحتمل أنك تنظر إلى كمية صغيرة من استخدام الذاكرة أو نتيجة ثابتة أو خطية طفيفة في الوقت المناسب.

فيما يتعلق بالأداء، فإن foreach يستهلك أكثر من for

http://forums.asp.net/p/1041090/1457897.aspx

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top