GORAGOD.com

เปรียบเทียบการค้นหาข้อความด้วย PHP แบบไม่สนใจขนาดตัวอักษร

วิธีการค้นหาข้อความด้วย PHP มีหลายวิธีครับ ในบทความนี้จะเป็นการเปรียบเทียบการค้นหาข้อความ แบบ ไม่สนใจขนาดตัวอักษร (ตัวพิมพ์ใหญ่และตัวพิมพ์เล็กเป็นตัวเดียวกัน)
  • แบบแรก เป็นการใช้ฟังก์ชั่น preg_match() โดยมีการเติม flag i
    $res = preg_match("/$find/i", $testString);
  • แบบที่สอง ทำการการแปลงตัวอักษรเป็นตัวพิมพ์เล็กให้เหมือนกันทั้งคำค้น และ ข้อความ ก่อนที่จะค้นหาด้วย strpos()
    $findx = strtolower($find);
    $res = strpos(strtolower($testString), $findx);
  • แบบที่สาม เป็นการใช้ฟังก์ชั่น stripos() ซึ่งเป็นฟังก์ชั่นที่ทำหน้าที่นี้โดยตรง
    $res = stripos(strtolower($testString), $findx);
ผลการทดสอบบน PHP 4 เวอร์ชั่นในเครื่องเดียวกัน
Current PHP version: 5.2.17
0.01408371925354 (preg_match)
0.0082025766372681 (strpos)
0.007812511920929 (stripos)

Current PHP version: 5.4.45
0.012207043170929 (preg_match)
0.0078847289085388 (strpos)
0.0068561196327209 (stripos)

Current PHP version: 5.6.14
0.011764943599701 (preg_match)
0.007383394241333 (strpos)
0.0066219925880432 (stripos)

Current PHP version: 7.1.0-dev
0.0036920785903931 (preg_match)
0.0055762052536011 (strpos)
0.0064772725105286 (stripos)

ผลการทดสอบแสดงออกได้หลายๆอย่าง ผมสรุปแบบนี้นะครับ
  • ใน PHP5 ฟังก์ชั่น stripos ซึ่งเป็นฟังก์ชั่นที่ทำหน้าที่นี้โดยตรง ทำงานได้เร็วที่สุด และที่ช้าที่สุดคือ preg_match
  • ใน PHP7 ฟังก์ชั่น preg_match ทำงานได้เร็วที่สุด ในขณะที่ stripos กลับทำงานได้ช้าที่สุด
  • ผลการทดสอบแสดงว่าฟังก์ชั่น preg_match ถูกพัฒนาไปเยอะมากใน PHP เวอร์ชั่น 7 ในขณะที่ฟังก์ชั่น stripos แทบไม่เปลี่ยนแปลงเลย (สงสัยว่ามันเตรียมตัวที่จะถูกถอดออกหรือเปล่า) ส่วน strpos ก็ยังมีการพัฒนาอยู่บ้าง

โค้ดที่ใช้ในการทดสอบ
// จำนวนครั้งการทดสอบ
$max = 10000;
// จำนวนรอบการทดสอบ ผลลัพท์เฉลี่ยจากค่านี้
$count = 20;
// แอเรย์เก็บผลลัพท์
$ret = array(0, 0, 0);
// ข้อมูล
$testString = 'I tried the same thing again, but this time I used a string only 2 characters longer (one at each end) than the string being matched by the functions. Here are the average times taken, in order.';
$find = "time i used";
for ($m = 0; $m < $count; $m++) {
    // preg_match
    $start = microtime(true);
    for ($z = 0; $z < $max; $z++) {
        $res = preg_match("/$find/i", $testString);
    }
    $ret[0] += microtime(true) - $start;

    // strpos
    $start = microtime(true);
    $findx = strtolower($find);
    for ($z = 0; $z < $max; $z++) {
        $res = strpos(strtolower($testString), $findx);
    }
    $ret[1] += microtime(true) - $start;

    // stripos
    $start = microtime(true);
    for ($z = 0; $z < $max; $z++) {
        $res = stripos($testString, $find);
    }
    $ret[2] += microtime(true) - $start;

    usleep(10240);
}
echo 'Current PHP version: '.phpversion().'<br>';
echo ($ret[0] / $count).' (preg_match)<br>';
echo ($ret[1] / $count).' (strpos)<br>';
echo ($ret[2] / $count).' (stripos)<br>';