Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> PHP

ประสิทธิภาพ FOR vs FOREACH ใน PHP

เปรียบเทียบประสิทธิภาพของ for loop และ foreach loop ใน PHP รวมถึงเทคนิค Optimization

ความแตกต่างพื้นฐาน

  • for loop: ทำงานกับ Index โดยตรง เข้าถึง Element ผ่าน $arr[$i]
  • foreach loop: ทำงานกับ Iterator ภายใน PHP คัดลอก Array (Copy-on-Write) สำหรับ Value

Benchmark: Loop 10,000 รอบ แก้ไขค่า

 $v) {
    $arr[$k] = $v + 1; // เขียนกลับผ่าน Key
}
echo "foreach (value copy): " . (microtime(true) - $start) . "s\n";

// 2. foreach แบบ Reference (&$v) - แก้ไขตรง
$start = microtime(true);
foreach ($arr as $k => &$v) {
    $v = $v + 1; // แก้ไข Reference โดยตรง
}
unset($v); // สำคัญ: Unset Reference หลัง Loop!
echo "foreach (reference): " . (microtime(true) - $start) . "s\n";

// 3. for loop
$start = microtime(true);
for ($i = 0, $count = count($arr); $i < $count; $i++) {
    $arr[$i] = $arr[$i] + 1;
}
echo "for loop: " . (microtime(true) - $start) . "s\n";

// 4. foreach อ่านอย่างเดียว (ไม่แก้ไข)
$start = microtime(true);
foreach ($arr as $k => $v) { }
echo "foreach (read only): " . (microtime(true) - $start) . "s\n";

/* ผลลัพธ์ประมาณ (PHP 8.1):
foreach (value copy): 0.0012s
foreach (reference):  0.0008s  <-- เร็วที่สุดสำหรับแก้ไข
for loop:             0.0010s
foreach (read only):  0.0003s  <-- เร็วที่สุดสำหรับอ่านอย่างเดียว
*/

การวิเคราะห์

Scenarioเร็วที่สุดเหตุผล
อ่านอย่างเดียว (Read-only)foreachInternal Iterator เร็วกว่า Index Lookup
แก้ไขค่า (Modify)foreach + Reference (&$v)ไม่ต้อง Lookup $arr[$k] ซ้ำ
ต้องการ Index/Keyforeach ($arr as $k => $v)ได้ Key และ Value พร้อมกัน
ข้าม Index (Step > 1)for loopควบคุม Index ได้เต็มที่
Loop ย้อนกลับfor loop$i-- ง่ายกว่า

⚠️ ข้อควรระวัง: Reference ใน Foreach

$arr = [1, 2, 3];

foreach ($arr as &$v) {
    $v *= 2;
}
unset($v); // สำคัญมาก!

// ถ้าไม่ unset($v):
$v = 999; // $arr[2] จะกลายเป็น 999! (เพราะ $v ยัง Reference อยู่)

// ปัญหาใน Nested Loop:
foreach ($arr as &$v) { ... }
foreach ($arr as $v) { ... } // $v ใน Loop ที่ 2 เป็น Reference ของ Element ตัวสุดท้าย!
// แก้: unset($v) ระหว่าง Loop หรือใช้ชื่อ Variable ต่างกัน

Optimization Tips

  1. Cache count(): for ($i=0, $c=count($arr); $i<$c; $i++)
  2. หลีกเลี่ยง Function Call ใน Loop: ย้าย count(), sizeof() ออกมา
  3. ใช้ Reference เมื่อ Modify: foreach ($arr as &$v) + unset($v)
  4. Array Functions: array_map, array_filter, array_reduce มักเร็วกว่า Loop แบบ Manual (C-level)

Modern PHP: Array Functions vs Loops

$arr = range(1, 100000);

// แบบเดิม: foreach
$start = microtime(true);
$result = [];
foreach ($arr as $v) {
    $result[] = $v * 2;
}
echo "foreach: " . (microtime(true) - $start) . "s\n";

// แบบ Modern: array_map (C-level, เร็วกว่า)
$start = microtime(true);
$result = array_map(fn($v) => $v * 2, $arr);
echo "array_map: " . (microtime(true) - $start) . "s\n";

/* ผลลัพธ์:
foreach: 0.008s
array_map: 0.004s  <-- เร็วกว่า ~2x
*/