การเพิ่มประสิทธิภาพอาร์เรย์ที่ไม่จำเป็นใน PHP

สมมติว่ามีโปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้ หาผลรวมของจำนวนเต็มตั้งแต่ 1 ถึง 100000000

โปรแกรมเมอร์ของเราได้เขียนโซลูชั่นที่สวยงาม สำหรับงานนี้ ดังนี้:

php<?php
  echo array_sum(range(1, 100000000));
?>

เป็นโซลูชั่นที่สวยงามใช่ไหมล่ะ? แค่บรรทัดเดียว และอะไรทำนองนั้น แต่มันไม่ทำงาน! ลองรันโค้ดนี้ดู แล้วมันจะแสดงข้อผิดพลาดออกมาว่าคุณได้ร้องขอ หน่วยความจำมากเกินไป

อืม, 100000000 ดูเหมือนจะไม่มากเท่าไหร่นะ? หรือมาก? ลองคำนวณดู ฟังก์ชัน range สร้างอาร์เรย์ที่มีตัวเลข 100000000 ตัว สมมติว่า PHP จองหน่วยความจำสำหรับตัวเลขตัวละ 2 ไบต์ - ดังนั้นการเก็บอาร์เรย์ของเราจะต้องใช้ 200000000 ไบต์ ซึ่งก็คือประมาณ 200 เมกะไบต์ของหน่วยความจำ

แต่จริงๆแล้วจะต้องใช้หน่วยความจำมากกว่านั้นมาก เพราะว่าใน PHP มีค่าใช้จ่ายส่วนเพิ่ม (overhead) จำนวนมาก ในการเก็บอาร์เรย์ ตัวอย่างเช่น ในข้อความผิดพลาดของฉัน มันแจ้งว่า ฉันกำลังพยายามจอง 4294967304 ไบต์ - ซึ่งก็คือประมาณ 4 กิกะไบต์!

ตอนนี้เข้าใจแล้วว่าทำไมถึงเกิดข้อผิดพลาด - เราเกินขีดจำกัดหน่วยความจำที่อนุญาตไปไกลมาก

มันไม่ยากเลยที่จะเขียนสคริปต์ของเราใหม่ให้เป็นอีกแบบหนึ่ง ที่แทบไม่ใช้หน่วยความจำเลย:

php<?php
  $sum = 0;
  
  for ($i = 1; $i <= 100000000; $i++) {
    $sum += $i;
  }
  
  echo $sum;
?>

หรือจะดีกว่าถ้าเราใช้วิธีทางคณิตศาสตร์:

php<?php
  $n = 1000000;
  $sum = $n * ($n + 1) / 2;
  echo $sum;
?>
Задание 1

โปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้หา แฟกทอเรียลของตัวเลขที่กำหนด เขาแก้ปัญหาด้วยวิธีต่อไปนี้:

php<?php
  $n = 100;
  echo array_product(range(1, $n));
?>

อธิบายว่าอะไรผิดปกติกับโค้ดนี้ แก้ไขโค้ด ให้มีประสิทธิภาพมากขึ้น

Задание 2

โปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้หา จำนวนตัวเลขที่สามารถใช้เขียนจำนวนเต็มทั้งหมดตั้งแต่ 1 ถึง 1000000 ได้ เขาแก้ปัญหาด้วยวิธีต่อไปนี้:

php<?php
  echo strlen(implode('', range(1, 1000000)));
?>

อธิบายว่าอะไรผิดปกติกับโค้ดนี้ แก้ไขโค้ด ให้มีประสิทธิภาพมากขึ้น

Задание 3

โปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้หา จำนวนตัวเลขที่หารด้วย 7 ลงตัว ภายในช่วงที่กำหนด เขาแก้ปัญหาด้วยวิธีต่อไปนี้:

php<?php
  $arr = [];
  
  for ($i = 0; $i <= 1000; $i++) {
    if ($i % 7 == 0) {
      $arr[] = $i;
    }
  }
  
  echo count($arr);
?>

อธิบายว่าอะไรผิดปกติกับโค้ดนี้ แก้ไขโค้ด ให้มีประสิทธิภาพมากขึ้น

Задание 4

โปรแกรมเมอร์คนหนึ่งได้รับมอบหมายงานให้หา ผลรวมของตัวหารของตัวเลข เขาแก้ปัญหาด้วยวิธี ต่อไปนี้:

php<?php
  $num = 320;
  $divs = [];
  
  for ($i = 0; $i <= $num; $i++) {
    if ($num % $i == 0) {
      $divs[] = $i;
    }
  }
  
  echo array_sum($divs);
?>

อธิบายว่าอะไรผิดปกติกับโค้ดนี้ แก้ไขโค้ด ให้มีประสิทธิภาพมากขึ้น