Tối ưu hóa các mảng không cần thiết trong PHP
Giả sử một lập trình viên đứng trước nhiệm vụ
tìm tổng các số nguyên từ 1 đến 100000000.
Lập trình viên của chúng ta đã viết một giải pháp tinh tế cho nhiệm vụ này, như thế này:
<?php
echo array_sum(range(1, 100000000));
?>
Giải pháp đẹp, phải không? Chỉ một dòng và tất cả những thứ như vậy. Nhưng nó không hoạt động! Hãy thử chạy mã này và nó sẽ đưa ra màn hình lỗi rằng bạn đã yêu cầu quá nhiều bộ nhớ.
Hmm, 100000000 dường như không nhiều lắm?
Hay là nhiều? Hãy tính toán. Hàm range
tạo ra một mảng với 100000000 số.
Giả sử PHP cấp phát 2 byte
cho một số
- khi đó để lưu trữ mảng của chúng ta sẽ cần
200000000 byte, tức là khoảng
200 megabyte bộ nhớ.
Nhưng thực tế sẽ cần nhiều bộ nhớ hơn
rất nhiều do PHP có
chi phí phụ rất lớn khi lưu trữ mảng.
Ví dụ, trong văn bản lỗi của tôi hiển thị,
rằng tôi đang cố gắng cấp phát 4294967304
byte - khoảng 4 gigabyte!
Bây giờ đã rõ tại sao lỗi xảy ra - chúng ta đã vượt xa giới hạn bộ nhớ cho phép.
Không khó để viết lại script của chúng ta thành một script khác, hầu như không tiêu thụ bộ nhớ:
<?php
$sum = 0;
for ($i = 1; $i <= 100000000; $i++) {
$sum += $i;
}
echo $sum;
?>
Hoặc thậm chí tốt hơn, hãy sử dụng giải pháp toán học:
<?php
$n = 1000000;
$sum = $n * ($n + 1) / 2;
echo $sum;
?>
Một lập trình viên đứng trước nhiệm vụ tìm giai thừa của một số cho trước. Anh ấy đã giải quyết nó như sau:
<?php
$n = 100;
echo array_product(range(1, $n));
?>
Giải thích điều gì không ổn với mã này. Hãy viết lại mã thành tối ưu hơn.
Một lập trình viên đứng trước nhiệm vụ tìm
số lượng chữ số có thể được sử dụng để
viết tất cả các số nguyên từ 1 đến 1000000.
Anh ấy đã giải quyết nó như sau:
<?php
echo strlen(implode('', range(1, 1000000)));
?>
Giải thích điều gì không ổn với mã này. Hãy viết lại mã thành tối ưu hơn.
Một lập trình viên đứng trước nhiệm vụ tìm
số lượng các số chia hết cho
7, nằm trong một
khoảng cho trước. Anh ấy đã giải quyết nó như sau:
<?php
$arr = [];
for ($i = 0; $i <= 1000; $i++) {
if ($i % 7 == 0) {
$arr[] = $i;
}
}
echo count($arr);
?>
Giải thích điều gì không ổn với mã này. Hãy viết lại mã thành tối ưu hơn.
Một lập trình viên đứng trước nhiệm vụ tìm tổng các ước số của một số. Anh ấy đã giải quyết nó như sau:
<?php
$num = 320;
$divs = [];
for ($i = 0; $i <= $num; $i++) {
if ($num % $i == 0) {
$divs[] = $i;
}
}
echo array_sum($divs);
?>
Giải thích điều gì không ổn với mã này. Hãy viết lại mã thành tối ưu hơn.