Page 1 of 1

ETA

Posted: Fri Oct 28, 2011 1:15 pm
by Rescator

Code: Select all

;Function ETA(), Public Domain.
;This is an attempt to make a ETA function as simple as possible while remaining as accurate as possible.
;"It can scarcely be denied that the supreme goal of all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience" - Albert Einstein
;or "As simple as possible, but no simpler." if paraphrased.
;And why not more advanced/complex estimations? Because there is no way to reliably estimate the future. (bit-rate changes)
;This is also auto-correcting without the need for a rule-set, and is as basic as you can get, hence why this is put in the Public Domain instead.
;totalsize is the total size of the file/data, value is in bytes.
;currentsize is how many bytes has been downloaded/processed so far.
;starttime is the Date() when the current transfer/session/processing started.
;currenttime is the current Date().
;The ETA (Estimated Time of Arrival -military term) is returned as a Date() value.
;The ETA() procedure can be called as many times as desired,
;the longer (more) data has been downloaded or processed the more accurate the ETA will be.
;This routine may look very simple, but still a lot of programs (and developers) manage to get this wrong for some odd reason.


Procedure.l ETA(totalsize.q,currentsize.q,starttime.l,currenttime.l)
	Protected eta.d
	eta=Round(starttime+(totalsize/(currentsize/(currenttime-starttime))),#PB_Round_Up)
	ProcedureReturn eta
EndProcedure


Define etatime.l,totalsize.q,currentsize.q,starttime.l,currenttime.l


;time from Date()
starttime=1319798179
currenttime=1319800422


;size in bytes
totalsize=3715146711
currentsize=688914432


;Bonus: How to calculate/show percentage done.
Debug "Progress: "+StrD((currentsize/totalsize)*100.0,2)+"%"


;Bonus: how to calculate/show average speed.
;(?*0.000008) or (?/125000) is the same as doing ((?/1000)*8) multiply is fastest but could have some rounding issues.
Debug "Avg. Bit-rate: "+StrD((currentsize/(currenttime-starttime))*0.000008,2)+" mbit/s"
Debug ""

;This shows the exact date/time of the ETA,
;usually the number of hours remaining is shown in programs,
;but personally I like seeing the specific date/time instead,
;we also avoid having to do "time remaining" calculations/conversions this way.
etatime=ETA(totalsize,currentsize,starttime,currenttime)

Debug "Start: "+FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss",starttime)
Debug "Now: "+FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss",currenttime)
Debug ""
Debug "ETA: "+FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss",etatime)


;The same value should be shown on both x86 and x64 (faster doubles on x64),
;and be 1319810275 with the default time and size values, if it's not then there was a rounding error/precision loss.
;during testing if the ETA() procedure was done slightly different 1319810304 was returned, which is a error of 29 sec.
Debug ""
Debug "Debug: "+Str(etatime)+" should be 1319810275 using the test values"


;In this example the ETA is 3:21 hours,
;the test values was taken from a real life situation,
;the values/state was taken after only 18.5% was downloaded,
;in this case the ETA() routine was off by only 25 minutes (it actually took 2:55 hours).
;Please remember that the more bytes that are downloaded or processed the more accurate the ETA becomes.
;ETA() can be used with anything that has a known total size, handles the data in some way,
;and you are able to somewhat periodically call ETA().
;This example is just that, normally you use ETA() in a loop up to once per second and display this to the user.
;but you have to admit that a single data-point at 18.5% completion not being off by more than 25 min is pretty darn good.


;Examples: downloading, file-copying, audio or video conversion (use the input data size and data read total).
;Actually totalsize and currentsize does not even need to be byte values,
;in the case of database processing you may have number of total lines and lines processed so far,
;so use those as the totalsize and currentsize instead.
;As long as you can enumerate the total "size" of a job and how much of the job has been done,
;then you can use ETA() to get the estimated time for when the job or task is finished.


;Since this ETA() is based on empirical data (what has been processed, past history, or fact) it may not be as responsive,
;if the speed (like during torrents downloading which can have very large fluctuating average bit-rates) then ETA() will
;take a longer time to reflect this, but in return ETA() is also more consistent/stable in it's estimate.


;Please note that if the processing/transfer is halted or paused and then continued,
;it is wisest to "pretend" that you have started over again, only this time from where you continued,
;if you do not then the pause will be considered part of the "speed".
;Obviously in some cases you might actually want the pause to count as well, especially if these pauses are regular.
;What could be considered a pause? When at any time there is 0 bytes of data processed per second.


;Have fun! Regards, Rescator.


Re: ETA

Posted: Sat Oct 29, 2011 3:47 am
by BasicallyPure
Thanks,

This is going in my library.
I don't need it right now but quite possibly someday I will.