In general, if there is a sufficiently large file, no matter how optimal the algorithm, you will still run into the time limit. For obviously large tasks, it is disabled.
Let's see what and how it affects performance. I generated an array of 200k values ββand wrote it into a file. At the time of the end of generation, the amount of used memory ( memory_get_usage()
) was 29 MB.
Then I turned off the time limit ( set_time_limit(0)
) and started your script to check how long it will be executed, and the tone was completed after 770 seconds.
We assume that the main reason for the long processing is that the slice is executed 200k times (the long slice is not in itself, but it is likely that the memory manager constantly allocates something and the collector destroys it). If you replace array_sum(array_slice( ... ))
with a function that counts the sum of elements manually
$rangeSum = function($data, $s) use ($count){ $sum = 0; $end = min($s+30, $count); while($s < $end){ $sum += $data[$s++]; } return $sum; };
running time - 1.4 seconds.
The next option is to calculate the sum of the first 30 items. And move on along the array. Subtract the first, add the following:
$i = 0; while($i < 30) $sum += $arr[$i++]; $x = $sum > 50 ? 1 : 0; for($i = 30; $i < $count; $i++){<--> $sum += -$arr[$i-30] + $arr[$i]; if($sum > 50) $x++; }
Here I neglected the end of the array a little, and in fact I donβt count the last 30 sums, but the result is 0.25 sec.
There is another option - to read the file line by line. But since You will need to store the current 30 elements in the array and do shift / push each time (to store this -30 element), then its performance will be below ~ 0.35 seconds, but you always store only 30 values, not 200 thousand, so the memory consumption will be minimal .
while( ($v = fgets($f)) !== false){ $m = array_shift($values); $sum += -$m + $v; $values[] = $v; if($sum > 50) $x++; }
previously we have already counted the first 30 lines and summed it up.
PS: all of the above code is taken out of context and not complete, just to convey meaning
function rangeSum($arr, $start, $len = 30){ $sum = 0; while($len--) $sum+=$arr[$start++]; return $sum; }
function rangeSum($arr, $start, $len = 30){ $sum = 0; while($len--) $sum+=$arr[$start++]; return $sum; }
function rangeSum($arr, $start, $len = 30){ $sum = 0; while($len--) $sum+=$arr[$start++]; return $sum; }
can give a slight performance boost due to the elimination of 200k slices of the array (the end test must be true) - teran