Optimizacija nepotrebnih polj v PHP

Naj ima nek programer nalogo poiskati vsoto celih števil od 1 do 100000000.

Naš programer je napisal elegantno rešitev te naloge, takole:

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

Lepa rešitev, ali ne? V eni vrstici in vse to. Vendar ne deluje! Poskusite zagnati to kodo in pokazala vam bo napako o tem, da ste zahtevali preveč delovnega pomnilnika.

Hm, 100000000 ni videti tako veliko? Ali pa je? Preštejmo. Funkcija range ustvari polje z 100000000 števili. Naj PHP dodeli za število 2 bajta - potem bo za shranjevanje našega polja potrebno 200000000 bajtov, torej približno 200 megabajtov delovnega pomnilnika.

Toda v resnici bo potrebno veliko več delovnega pomnilnika zaradi tega, ker ima PHP zelo velike režijske stroške pri shranjevanju polja. Na primer, pri meni v besedilu napake piše, da poskušam dodeliti 4294967304 bajtov - kar je približno 4 gigabajtov!

Zdaj je jasno, zakaj se pojavi napaka - daleč smo presegli dovoljeno mejo pomnilnika.

Ni tako težko prepisati naš skript v drugega, ki praktično ne porabi delovnega pomnilnika:

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

Še bolje je uporabiti matematično rešitev:

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

Nek programer je imel nalogo poiskati fakulteto danega števila. Rešil jo je na naslednji način:

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

Pojasnite, kaj je narobe s to kodo. Predelajte kodo v bolj optimalno.

Задание 2

Nek programer je imel nalogo poiskati število števk, s katerimi lahko zapišemo vsa cela števila od 1 do 1000000. Rešil jo je na naslednji način:

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

Pojasnite, kaj je narobe s to kodo. Predelajte kodo v bolj optimalno.

Задание 3

Nek programer je imel nalogo poiskati število števil, deljivih brez ostanka z 7, ki se nahajajo v danem intervalu. Rešil jo je na naslednji način:

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

Pojasnite, kaj je narobe s to kodo. Predelajte kodo v bolj optimalno.

Задание 4

Nek programer je imel nalogo poiskati vsoto deliteljev števila. Rešil jo je na naslednji način:

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

Pojasnite, kaj je narobe s to kodo. Predelajte kodo v bolj optimalno.