การเพิ่มประสิทธิภาพอาร์เรย์ที่ไม่จำเป็นใน PHP
สมมติว่ามีโปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้
หาผลรวมของจำนวนเต็มตั้งแต่ 1 ถึง 100000000
โปรแกรมเมอร์ของเราได้เขียนโซลูชั่นที่สวยงาม สำหรับงานนี้ ดังนี้:
<?php
echo array_sum(range(1, 100000000));
?>
เป็นโซลูชั่นที่สวยงามใช่ไหมล่ะ? แค่บรรทัดเดียว และอะไรทำนองนั้น แต่มันไม่ทำงาน! ลองรันโค้ดนี้ดู แล้วมันจะแสดงข้อผิดพลาดออกมาว่าคุณได้ร้องขอ หน่วยความจำมากเกินไป
อืม, 100000000 ดูเหมือนจะไม่มากเท่าไหร่นะ?
หรือมาก? ลองคำนวณดู ฟังก์ชัน range
สร้างอาร์เรย์ที่มีตัวเลข 100000000 ตัว
สมมติว่า PHP จองหน่วยความจำสำหรับตัวเลขตัวละ 2 ไบต์
- ดังนั้นการเก็บอาร์เรย์ของเราจะต้องใช้
200000000 ไบต์ ซึ่งก็คือประมาณ
200 เมกะไบต์ของหน่วยความจำ
แต่จริงๆแล้วจะต้องใช้หน่วยความจำมากกว่านั้นมาก
เพราะว่าใน PHP มีค่าใช้จ่ายส่วนเพิ่ม (overhead) จำนวนมาก
ในการเก็บอาร์เรย์
ตัวอย่างเช่น ในข้อความผิดพลาดของฉัน มันแจ้งว่า
ฉันกำลังพยายามจอง 4294967304
ไบต์ - ซึ่งก็คือประมาณ 4 กิกะไบต์!
ตอนนี้เข้าใจแล้วว่าทำไมถึงเกิดข้อผิดพลาด - เราเกินขีดจำกัดหน่วยความจำที่อนุญาตไปไกลมาก
มันไม่ยากเลยที่จะเขียนสคริปต์ของเราใหม่ให้เป็นอีกแบบหนึ่ง ที่แทบไม่ใช้หน่วยความจำเลย:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
หรือจะดีกว่าถ้าเราใช้วิธีทางคณิตศาสตร์:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
โปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้หา แฟกทอเรียลของตัวเลขที่กำหนด เขาแก้ปัญหาด้วยวิธีต่อไปนี้:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
อธิบายว่าอะไรผิดปกติกับโค้ดนี้ แก้ไขโค้ด ให้มีประสิทธิภาพมากขึ้น
โปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้หา
จำนวนตัวเลขที่สามารถใช้เขียนจำนวนเต็มทั้งหมดตั้งแต่
1 ถึง 1000000 ได้
เขาแก้ปัญหาด้วยวิธีต่อไปนี้:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
อธิบายว่าอะไรผิดปกติกับโค้ดนี้ แก้ไขโค้ด ให้มีประสิทธิภาพมากขึ้น
โปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้หา
จำนวนตัวเลขที่หารด้วย 7 ลงตัว ภายในช่วงที่กำหนด
เขาแก้ปัญหาด้วยวิธีต่อไปนี้:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
อธิบายว่าอะไรผิดปกติกับโค้ดนี้ แก้ไขโค้ด ให้มีประสิทธิภาพมากขึ้น
โปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้หา ผลรวมของตัวหารของตัวเลข เขาแก้ปัญหาด้วยวิธี ต่อไปนี้:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
อธิบายว่าอะไรผิดปกติกับโค้ดนี้ แก้ไขโค้ด ให้มีประสิทธิภาพมากขึ้น