Calculating Time Remaining

For some reason I cannot think this evening :-/ The application currently displays the time elapsed during the “scan” but I’d like to include “Time remaining” as well.

So, we have bufferlength and usedbufferlength as integers.

Ive attempted getting the totalseconds remaining by taking:

((Bufferlength - usedbufferlength) / usedbufferlength) * knownsecondspassed

[Pseudo interpretation: (DistanceLeftToTravel/HowFarWeveTravelled)HowLongItsTakenToGetTheCurrentDistance]

But the return when converted to hours, minutes, and seconds is days…when I know it should only be minutes…if even an hour…

How would one suggest the time remaining be calculated in such an instance? I cannot see the mistake in the logic.

( knownsecondspassed / usedbufferlength ) * ( bufferlength - usedbufferlength )

Actually, that comes out to the same result so the problem has to be in your conversion.

[quote=90652:@Kem Tekinay] ( knownsecondspassed / usedbufferlength ) * ( bufferlength - usedbufferlength ) [/quote]

Ill have to post the app…the math all makes sense and seems correct but shows sporadic increasing and falling in hours, minutes, and seconds. :-/ for 2.1MB file its showing 18Hrs some minutes and seconds but is at 90%…showed 11hrs at 2% :-/

The totalsecondspassed is the same seconds used to calculate elapsed time (which is correct and comes out correct using the same method below…which is also attemptedly applied to try to calculate the remaining time)…

Dim TimeLeft as double = our equation above

Dim h, m, s as integer
Dim absoluteminutes as double

H=timeleft/3600
M=(timeleft/60) mod 60
Absoluteminutes = timeleft/60
S= TimeLeft-(absoluteminutes*60)

… then build the string with the H, M, S values…

Start time is a public double variable that is set as

Dim d as new date
StartTime = d.totalseconds

when the “scan” starts…

Here is the whole function.

Private Function TimePassed() As String
  Dim h, x, m, s as integer
  Dim th, tm,ts as integer
  Dim f as new date

  Dim DiffInSeconds as double = abs(f.TotalSeconds - StartTime)

//////////Time Remaining//////// Doesn't Work....
  Dim TimeLeft as Double = (DiffInSeconds/UsedBuffer)*(BufferLength-UsedBuffer)
  
  th = TimeLeft/3600
  tm = (TimeLeft/60) mod 60
  Dim absoluteminleft as integer = TimeLeft/60
  ts = TimeLeft - (absoluteminleft*60)
  

///TODO: cleanup with format and remove strings
  Dim th1 as string = str(th)
  Dim tm1 as string = str(tm)
  Dim ts1 as string = str(ts)
  
  if len(th1) = 1 then th1 = "0" + str(th)
  if len(tm1) = 1 then tm1 = "0" + str(tm)
  if len(ts1) = 1 then ts1 = "0" + str(ts)


//////////Time Elapsed///////// Does Work....  
  h = DiffInSeconds/3600
  m =(DiffInSeconds/60) mod 60
  Dim absoluteminutes as integer = DiffInSeconds/60
  s  = DiffInSeconds - (absoluteminutes*60)
  

///TODO: cleanup with format and remove strings
  Dim h1 as string = str(h)
  Dim m1 as string = str(m)
  Dim s1 as string = str(s)
  
  if len(h1) = 1 then h1 = "0" + str(h)
  if len(m1) = 1 then m1 = "0" + str(m)
  if len(s1) = 1 then s1 = "0" + str(s)
  
  
  return h1 + ":" + m1 + ":" + s1 + "  /  " + th1 + ": " + tm1 + ":" + ts1
  
End Function

I think you need to log all the values on each pass to see what’s changing on you. Otherwise, the math seems right.

Function TimePassed(percTodo as Double,tRef as Date) As pair dim tCurrent as new date tCurrent.TotalSeconds=tCurrent.TotalSeconds-tRef.TotalSeconds dim v() as String=tCurrent.SQLDateTime.Split(" ") dim TimePassed as String=v(1) tCurrent.TotalSeconds=tCurrent.TotalSeconds*percTodo v=tCurrent.SQLDateTime.Split(" ") Return TimePassed:v(1) End Function
Where percTodo is (BufferLength-UsedBuffer)/UsedBuffer and tRef is StartTime

Return a pair where left side is the Time Elapsed(string) and the right side is the Time Remaining (string)

Shouldn’t that be
((BufferLength - usedbufferlength) / BufferLength) * knownsecondspassed

How about this?

BufferLength –UsedBufferlength = BufferlengthRemaining
Speed = UsedBufferlength/KnownSecondsPassed

TimeRemaining = BufferlengthRemaining/ Speed

BufferLength –UsedBufferlength / UsedBufferlength/KnownSecondsPassed

(BufferLength –UsedBufferlength)* KnownSecondsPassed / UsedBufferlength

Lennox

My 2 cents:

Record the start time when the process starts. I do this by setting a property on the window:

StartTime = ticks

I also suggest keeping an array of calculated times. If something causes your app to slow down, this will auto compensate:

TotalSecondsCalcs() as Integer

You’ll need a method for only averaging the most recent calculations:

Private Function Avg(numbers() as Integer, count as integer) As Integer dim tot as integer dim c as integer = min(numbers.ubound,count - 1) for i as integer = 0 to c tot = tot + numbers(i) next i return tot/(c+1) End Function

Then call this method to calculate the number of seconds remaining.

[code]Private Function UpdateTimeRemaining(percentageComplete as Integer) As Integer
//What time is it now
dim currentTime as integer = ticks / 60

//How many seconds have elapsed
dim deltaSeconds as integer = currentTime - StartTime

//Based on the percentage complete, how many seconds will the whole process take
dim totalSeconds as integer = deltaSeconds / (percentageComplete/100)

//Add this value to the array
TotalSecondsCalcs.Insert 0,totalSeconds

//Get an average of the last 10 totals
dim averageTotal as integer = avg(totalSecondscalcs,10)

//Return the number of seconds we THINK it’s going to be
dim secondsRemaining as integer = averageTotal - deltaSeconds

return max(secondsRemaining,0)

End Function
[/code]

You may also want to make it say “Calculating…” while the array gets populated. Otherwise the original estimates will wildly vary.

Awesome guys thanks…so far this what I have… and the hours still seem out-rageous…although the seconds and minutes seem to be decreasing properly…I’ve included the source code…perhaps someone could shed some light on how to increase the “scanning” speed as well since the Xojo version takes almost an hour to “scan” a 10 MB file…while the old VB6 version takes less than 1 second to scan a 10MB file :-/ If indeed the time is reading correct it will take the xojo version 4396 hours 48 minutes and some seconds to scan the 10 MB file…Yikes!!!

Code: http://www.xojodevspot.com/demos/AppHacker.rar

Try this:

Private Sub ReadFile()
  
  Dim TMP() as String
  Static ValidCharSet as string = "abcdefghijklmnopqrstuvwxyzüöäÜÖÄß_-' 1234567890" + chr(34)
  Dim bChar as String
  
  dim bufferArr() as String = Buffer.Split( "" )
  'For i as integer = 1 To Len(Buffer)
  For i as Integer = 0 to bufferArr.Ubound
    'bChar = Mid(Buffer, i, 1)
    bChar = bufferArr( i )
    If InStr(0,ValidCharSet, bChar) <> 0 Then
      'Tmp = Tmp + bChar
      Tmp.Append bChar
      
      VisualData.Graphics.ForeColor = &cFF0000
      VisualData.Graphics.DrawRect(PixelX,PixelY,4,4)
      
    Else
      
      'If Len(Tmp) >= tLength Then
      If ( Tmp.Ubound + 1 ) >= tLength Then
        'KeyStrings.Append Trim(Tmp)
        KeyStrings.Append Trim( Join( Tmp, "" ) )
        Progress = round((i/BufferLength)*100)
      End If
      
      VisualData.Graphics.ForeColor = &c00FF00
      VisualData.Graphics.DrawRect(PixelX,PixelY,4,4)
      
      'Tmp = ""
      Redim Tmp( -1 )
    End If
    
    UsedBuffer = i
    Increment()
    
  Next i
  
  
End Sub

Wow kem thanks! I didn’t even think about string building takes more time than using straight arrays… it’s still slower than the VB6 version but 100 times faster now :slight_smile: now if I can solve the time remaining issue :slight_smile:

This formula produces correct results in my limited testing. What calculations are you using? And how are you then converting to hours/min/sec. Either one could be faulty.

The project with source code is here

Code: http://www.xojodevspot.com/demos/AppHacker.rar

It’s the original version without kems update to the scan function…

Sorry, I can’t read .rar files. Please post the relevant snippets.

gregs method.

(DiffInSeconds/UsedBuffer)* (BufferLength-UsedBuffer)

This seems to work now after all the variable time trouble…perhaps Kem’s magic and Tim popping in to help helped. I simply commented out Greg’s method call to updatetimeremaining and uncommented the original equation…and it just suddenly works :slight_smile:

Naturally I take full and complete credit.

You wouldn’t happen to know a good RegEx for “readable”/speakable words would you? I have a really long if/then based function to determine if the string passed to the function could possibly be a “real word” (is speakable anyway)…and I have a feeling it will really slow the application down once strings are compared against it :-/ I wouldn’t even know where to begin with such a regex since there are consonant and vowel rules…and the mix would be a disaster.