bauhsoj

08-31-2006, 08:56 PM

How would I estimate the time remaining to complete a loop if each run of the loop required a variable amount of time?

For instance, if I run an array 5 elements in size that runs in a foreach loop where it took 30, 20, 53, 40, and 32 seconds each run of the loop, how could I output the estimated time until completion in seconds as the loop is running?

I am terrible with math, yet I am a programmer...it is sad, I know. :o

run the code 100 times and take the average?

there are too many variable factors to give an accurate estimate, especially for such a small array.

giving a %-age progress is easier, but it wouldn't be worth except for really complex operations, as the time it takes to calculate the progress and display it is going to add to the time it takes.

What are you actually doing that you think would warrant this?

bauhsoj

08-31-2006, 09:12 PM

That was just a simplied example. The actual script has run anywhere from 10 minutes to 8 hours depending on the number of items it needs to parse and the complexity of the parsing requirements. At most the loop I am wanting to get the remaining time on can sometimes be upwards of 60,000 iterations.

harsh789

09-01-2006, 12:30 PM

Calculate avg time at run time of loop.

for example

if there are 100 items and it takes 2s for 1st the remaining time is 99*2s

then if it takes an avg 3s for 5 items remaining time is 95*3s and so on..

bauhsoj

09-01-2006, 08:51 PM

Here is what I have come up with and this seems to work....correctly I think.

/**

* Calculates the estimated time remaining based on the average processing time

* and the number of operations remaining.

* @return array

* @param int $last_elapsed_time Time in seconds the last observed operation required.

* @param int $total_count Total number of operations to be performed.

* @author bauhsoj

* @version $Revision: 1.0.0 $

*/

function time_remaining($last_elapsed_time, $total_count) {

static $count = 0; // Number of operations already performed.

static $total_time = 0;

$count++;

$total_time += $last_elapsed_time;

$average_time = $total_time / $count;

$r_array = array();

$diff = $average_time * ($total_count - $count);

$r_array['years'] = floor($diff / 60/60/24/365);

$diff -= $r_array['years'] * 60*60*24*365;

$r_array['months'] = floor($diff / 60/60/24/30);

$diff -= $r_array['months'] * 60*60*24*30;

$r_array['weeks'] = floor($diff / 60/60/24/7);

$diff -= $r_array['weeks'] * 60*60*24*7;

$r_array['days'] = floor($diff / 60/60/24);

$diff -= $r_array['days'] * 60*60*24;

$r_array['hours'] = floor($diff / 60/60);

$diff -= $r_array['hours'] * 60*60;

$r_array['minutes'] = floor($diff / 60);

$diff -= $r_array['minutes'] * 60;

$r_array['seconds'] = floor($diff);

$r_array['time_string'] = array();

$r_array['date_string'] = array();

if ($r_array['years'] != 0)

$r_array['date_string'][] = $r_array['years'].' year'.($r_array['years'] != 1 ? 's' : '');

if ($r_array['months'] != 0)

$r_array['date_string'][] = $r_array['months'].' month'.($r_array['months'] != 1 ? 's' : '');

if ($r_array['weeks'] != 0)

$r_array['date_string'][] = $r_array['weeks'].' week'.($r_array['weeks'] != 1 ? 's' : '');

if ($r_array['days'] != 0)

$r_array['date_string'][] = $r_array['days'].' day'.($r_array['days'] != 1 ? 's' : '');

if ($r_array['hours'] != 0)

$r_array['time_string'][] = $r_array['hours'].' hour'.($r_array['hours'] != 1 ? 's' : '');

if ($r_array['minutes'] != 0)

$r_array['time_string'][] = $r_array['minutes'].' minute'.($r_array['minutes'] != 1 ? 's' : '');

if ($r_array['seconds'] != 0)

$r_array['time_string'][] = $r_array['seconds'].' second'.($r_array['seconds'] != 1 ? 's' : '');

if (empty($r_array['date_string']))

$r_array['date_string'] = 'Today';

else

$r_array['date_string'] = implode(', ', $r_array['date_string']);

if (empty($r_array['time_string']))

$r_array['time_string'] = 'Now';

else

$r_array['time_string'] = implode(', ', $r_array['time_string']);

return $r_array;

}

Any comments?

bauhsoj

06-07-2007, 07:44 PM

After testing this code quite a bit I can safely say it does NOT give accurate remaining time. In fact, in my tests something that was timed as running for 5 minutes showed a time remaining of around 19 hours throughout the process.

Even taking out the averaging and just using the time required for the last loop to execute it is still wildly off.

Any ideas what I am doing wrong here?