GORAGOD.com

เปรียบเทียบความเร็วของฟังก์ชั่น array_merge และการผสานแอเรย์ด้วย PHP

เช่นเคยครับ ผมสงสัยว่าการผสานแอเรย์ด้วย array_merge เป็นวิธีที่ดีที่สุดหรือเปล่า เลยต้องมาทำการทดสอบ (benchmark)

เงื่อนไขแรก ใช้ฟังก์ชั่น array_merge ของ PHP
$a = array(1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
$b = array(6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine', 0 => 'zero');
$c = array_merge($a, $b);

เงื่อนไขที่สอง ใช้ฟังก์ชั่น for ในการวนลูปตัวแปร
$a = array('one', 'two', 'three', 'four', 'five');
$b = array('six', 'seven', 'eight', 'nine', 'zero');
$x = sizeof($a);
$l = sizeof($b);
for ($n = 0; $n < $l; $n++) {
   $a[$x + $n] = $b[$n];
}

เงื่อนไขที่สาม ใช้ฟังก์ชั่น foreach ในการวนลูปตัวแปร
$a = array(1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
$b = array(6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine', 0 => 'zero');
foreach ($b as $k => $v) {
   $a[$k] = $v;
}

ผมมีผลการทดสอบบน PHP 4 เวอร์ชั่นบนเครื่องเดียวมาฝาก
Current PHP version: 5.2.17
0.0079482078552246 (array_merge)
0.0055490970611572 (for)
0.0040394067764282 (foreach)

Current PHP version: 5.4.45
0.0077496528625488 (array_merge)
0.003299605846405 (for)
0.0025223016738892 (foreach)

Current PHP version: 5.6.14
0.0048038005828857 (array_merge)
0.0032832026481628 (for)
0.0022983074188232 (foreach)

Current PHP version: 7.1.0-dev
0.0021394014358521 (array_merge)
0.0022389531135559 (for)
0.0015640020370483 (foreach)

หลายๆคนอาจเคยคิดนะครับ ว่าฟังก์ชั่นเฉพาะของ PHP น่าจะมีประสิทธิภาพมากที่สุด แต่จากผลการทดสอบนี้จะเห็นว่าฟังก์ชั่นที่เขียนเองอาจจะมีประสิทธิภาพดีกว่าก็ได้

ข้อสังเกตุอีกอย่างนะครับ การใช้ฟังก์ชั่น foreach และ การใช้ฟังก์ชั่น array_merge หรือ for จะให้ผลลัพท์แตกต่างกันเล็กน้อย
การใช้ foreach จะสามารถรักษาค่าคีย์เดิมไว้ได้
Array (
    [1] => one
    [2] => two
    [3] => three
    [4] => four
    [5] => five
    [6] => six
    [7] => seven
    [8] => eight
    [9] => nine
    [0] => zero
)

ในขณะที่การใช้ฟังก์ชั่น array_merge และ ฟังก์ชั่น for จะคืนค่าคีย์เป็น 0 1 2 .....
Array (
    [0] => one
    [1] => two
    [2] => three
    [3] => four
    [4] => five
    [5] => six
    [6] => seven
    [7] => eight
    [8] => nine
    [9] => zero
)

โค้ดที่ใช้ในการทดสอบครับ
// จำนวนครั้งการทดสอบ
$max = 100000;
// จำนวนรอบการทดสอบ ผลลัพท์เฉลี่ยจากค่านี้
$count = 20;
// แอเรย์เก็บผลลัพท์
$ret = array(0, 0, 0);
for ($m = 0; $m < $count; $m++) {
    // test 1
    $a = array(1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
    $b = array(6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine', 0 => 'zero');
    $start = microtime(true);
    for ($z = 0; $z < $max; $z++) {
        $c = array_merge($a, $b);
    }
    $ret[0] += microtime(true) - $start;

    // test 2
    $a = array('one', 'two', 'three', 'four', 'five');
    $b = array('six', 'seven', 'eight', 'nine', 'zero');
    $x = sizeof($a);
    $start = microtime(true);
    for ($z = 0; $z < $max; $z++) {
        $l = sizeof($b);
        for ($n = 0; $n < $l; $n++) {
            $a[$x + $n] = $b[$n];
        }
    }
    $ret[1] += microtime(true) - $start;

    // test 3
    $a = array(1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
    $b = array(6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine', 0 => 'zero');
    $start = microtime(true);
    for ($z = 0; $z < $max; $z++) {
        foreach ($b as $k => $v) {
            $a[$k] = $v;
        }
    }
    $ret[2] += microtime(true) - $start;

    sleep(1);
}
echo 'Current PHP version: '.phpversion().'<br>';
echo ($ret[0] / $count).' (array_merge)<br>';
echo ($ret[1] / $count).' (for)<br>';
echo ($ret[2] / $count).' (foreach)<br>';