Announcement

Collapse
No announcement yet.

Progress bar boggs down app

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Progress bar boggs down app

    I have this app going that encrypts files as well as other things, and it is LIGHTNING quick..
    But when I put a progress bar on the dialog box and then put the stepit command inside my RC4 encryption, which normally does a 5 meg file in less than 5 seconds, it bogs down and takes almost 30 seconds.
    I also noticed this on the compression, took 5 times longer to compress a file...


    Is this normal behavior?

    Here's a snippet of what it's doing:


    Code:
    Control Add "msctls_progress32",pDlg,%PROGRESS2,"",5,25,185,12, %WS_CHILD Or %WS_VISIBLE Or %WS_CLIPSIBLINGS Or %CCS_BOTTOM
    
    'In the function, a new thread function:
    
        Control Set Text pDlg,%FILECOPYLABEL1,"Encrypting data, Please wait.."
        Control Send pDlg, %PROGRESS2, %PBM_SETRANGE, 0 ,MakLng(0,Len(Buffer)) 'Halfway, compression is the other half
        Control Send pDlg, %PROGRESS2, %PBM_SETSTEP, 1 , 0
    
    and inside the RC4 encryption scheme, without this SINGLE line of code it's back to 5 megs in 5 seconds or so (approx)
    
    
    For x = 0 To Len(St)-1
        Control Send pDlg, %PROGRESS2, %PBM_STEPIT, 1 , 0
        c = @p[x]
        i = (i + 1) Mod 256
        j = (j + s(i)) Mod 256
        Swap s(i), s(j)
        t = (s(i) + s(j)) Mod 256
        k = s(t)
        @pp[fromEncPos] = c Xor k
        Incr fromEncPos
    Next
    ------------------
    Scott
    mailto:[email protected]r.net[email protected]</A>
    Scott Turchin
    MCSE, MCP+I
    http://www.tngbbs.com
    ----------------------
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

  • #2
    too many updates!

    if your encrypt data is 5 megs then that's 5,000,000 updates!

    Make the length of the bar "MakLng(0,Len(Buffer)/100)"
    then stip it with

    if x mod 100 = 0 then
    Control Send pDlg, %PROGRESS2, %PBM_STEPIT, 1 , 0
    end if

    inside the for/next loop.

    the p-bar will often not quite finish so you have the last step after the loop finishes to make it look clean
    use a constant rather than "100" though so you can test a few different interations

    unnecessary updates of the GUI are often the cause of poor performance



    ------------------

    Paul Dwyer
    Network Engineer
    Aussie in Tokyo
    (Paul282 at VB-World)

    Comment


    • #3
      Paul is absolutely right. Most common slowdown is un-neccesary updates.
      On top of this, ProgressBar actually *is* a bit slow, so for really
      time critical code, it's better to use custom-built one. I know Semen,
      and maybe someone else too, has posted good samples of this to source code.

      BTW, count the number of bars you have on full ProgressBar and use
      that with the MOD operator. No point in updating more than needed.
      Common to have some 40 bars or so when it's near finish, so before
      loop, do a "ud& = Len(St) \ 40" '(50, 60, whatever) and in loop:
      Code:
      IF x MOD ud& = 0 THEN
        Control Send pDlg, %PROGRESS2, %PBM_STEPIT, 1 , 0"
        DIALOG DOEVENTS
      END IF
      DIALOG DOEVENTS? Yes, even if code runs fast, it may be wise to
      include this, because otherwise system is freezed up completely
      while code is running. Not necessary to do, but often recommended..


      ------------------

      Comment


      • #4
        Duh!!!!! Thank you guys! hehe, My brain was just not working, the answer was right there, percentage bar uses a percentage....

        Sheesh... I'm almost ashamed on this one! hehe


        Scott


        ------------------
        Scott
        mailto:[email protected][email protected]</A>
        Scott Turchin
        MCSE, MCP+I
        http://www.tngbbs.com
        ----------------------
        True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

        Comment


        • #5
          Scott;

          Here is how I handle something like a Progress bar (the principle
          can be used for other things):

          The mix max values should most always be 0 to 100.

          Calculate your progress bars position always as a percent (0 to 100)
          from whatever data you are working with. Keep the current value of
          the progress bar in a Global variable and then when a new value is
          calculated, check first to see if it is the same as the current
          value. If it is, then simply don't send a message to the progress bar
          to change it.

          Lets imagine the data values being used range from 0 to 5000.

          Here is some Pseudo code to demonstrate:

          Code:
          Global  CurrentPBarVal&
          CurrentPBarVal&=0
          
          ....
          ' processing data
          ' ActualVal! will be from 0 t0 5000
          PBarVal&=INT((ActualVal!/5000)*100)
          IF PBarVal&<>CurrentPBarVal& THEN
              ' Send message to PBar to update position to PBarVal&
          END IF
          Using similiar code to the above, you will elimiate nearly all of
          unnecessary repaints of the PBar control !

          Using the example above of 5000 updates, the PBar would only be updated
          100 times, rather than 5000 times (a speed increase of 50 to 1).

          It is amazing how often experienced programmers forget this
          simple technique.



          ------------------
          Chris Boss
          Computer Workshop
          Developer of "EZGUI"
          http://cwsof.com
          http://twitter.com/EZGUIProGuy

          Comment


          • #6
            OK So far so good but it still has some drag on the process, the process is still twice as fast if not faster when no progress bar is used..
            So tht's the price of letting the user know we're working.


            Question #2 is I want to have a second progress bar for TOTAL completion.
            This includes encryption and compression.

            I have 10 files lets say, g_FileIndex=10, I set the range to g_FileIndex/2.

            This takes me half way when all the compression is done.

            Now, I have encryption to do but it's encryptign ALL of the files in one buffer..

            That would be len(Buffer).

            Can I set the set to change in mid stream?
            Ie the progress bar is halfway because compression is done, now we hae say 5k of data to encrypt.

            It's a numbers game and I'm not getting hte numbers right in this case...

            Basic question: Can I change the SETSTEP in midstream?

            Code:
            'Progress1 is each file compression, and then total buffer compressoin and it works great.
            
            'If use encryption is selected then encrypt buffer at one time
            'STEPIT Is done in the encryption function.
            If IsTrue g_UseEncr Then
                Control Set Text pDlg,%FILECOPYLABEL1,"Encrypting data, Please wait.."
            '    Control Disable pDlg,%FILECOPYIDCANCEL
                Control Set Text pDlg, %FILECOPYLABEL2,""
                Control Send pDlg, %PROGRESS1, %PBM_SETRANGE, 0 ,MakLng(0,Len(Buffer)/100)
                Control Send pDlg, %PROGRESS1, %PBM_SETSTEP, 1 , 0
                Control Send pDlg, %PROGRESS2, %PBM_SETSTEP, MakLng(0,Len(Buffer)/100),0
                'Encrypt the files
                Buffer = RC4NcryptString(Buffer,"2F3C352644264028525A545C5C555029") 'Test key
            End If
            ------------------
            Scott
            mailto:[email protected][email protected]</A>
            Scott Turchin
            MCSE, MCP+I
            http://www.tngbbs.com
            ----------------------
            True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

            Comment


            • #7
              Scott --
              Alone, what you need - %PBM_SETPOS.
              Reread Chriss's suggestions once again.



              ------------------
              E-MAIL: [email protected]

              Comment


              • #8
                For "speed critical" sections of code where lot's of work is being done I often use a simple label to print out a step count or a percentage... of course update it as little as possible.

                If the “is time to update” comparison is slowing you down to much as well then maybe use a timer message to interrupt your loop only once a second?

                This doesn't look as nice but won't slow you down. You just have to decide what is more important: looks or speed.

                That ARC4 code from a while back was fun to play with and useful too! Thanks again for posting it.

                Colin Schmidt

                ------------------
                Colin Schmidt & James Duffy, Praxis Enterprises, Canada
                [email protected]

                Comment


                • #9
                  Thanks everyone!
                  SPeed is critical and I'm going to talk to the boss guy on this and see about just putting an animated icon in, something that moves.
                  The progress bar is so slow, even updating every 100 counts its' 10 times slower exactly (Timed it)...

                  It looks pretty but it's such a waste of resources.
                  Kinda like putting a supercharged V8 in my brother's Pinto but hten putting the original 4 banger carbuerator back on it.
                  Why slow PB down that much, it crunches 10 megs of data in 10 seconds flat, or 60 seconds (or more) with a progress bar..





                  Love that RC4, I'm encrypting everything that needs to be encrypted and I have a lot of SETI packets being used as seed value to derive the key hehehe Natural Space noise, nothing in this universe is more random (Unless it's a real ET signal that is hehe)


                  Scott


                  ------------------
                  Scott
                  mailto:[email protected][email protected]</A>
                  Scott Turchin
                  MCSE, MCP+I
                  http://www.tngbbs.com
                  ----------------------
                  True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                  Comment


                  • #10
                    Hey Scott,

                    I found myself in the same position so I wrote a custom progress bar. Making your own can seem a bit of an overkill but think about the advantages...

                    1. make it look the way you want.
                    2. optimize to no end.
                    3. no need to worry about MS changing the API.

                    Cheers!

                    ------------------
                    Cheers

                    [This message has been edited by mark smit (edited February 03, 2001).]

                    Comment


                    • #11
                      Actually I went back and tested on 1 meg files, same time.
                      So this code works...
                      But I didnt' do the ActualVar! in there, what is that ActualVar! ?? Is that the same as the value Len(Buffer)???

                      What if it's over 5000?


                      THis might work....
                      The compression is slow, but uncompression is fast anyway so that's the important part..

                      Scott

                      ------------------
                      Scott
                      mailto:[email protected][email protected]</A>
                      Scott Turchin
                      MCSE, MCP+I
                      http://www.tngbbs.com
                      ----------------------
                      True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                      Comment


                      • #12
                        Scott,

                        I think what they are saying is to let the progress bar display
                        a percentage and only update it when the percentage changes.

                        percentdone& = (amtProcessed&/amtToProcess&) * 100

                        If percentdone& > lastamtupdated& then
                        update progressbar
                        lastamtupdated = percentdone&
                        End if

                        set the progress bar to range from 0 to 100 ...

                        that handles all cases .. a 100 byte file to 100meg file. and only calls
                        the update progressbar a maximum of 100 times.

                        Mike


                        ------------------

                        Comment


                        • #13
                          Hello,

                          I don’t get as much time to play as I would like. But I could justify this one as I will need something simular myself down the road. RE my earlier posting: I guess people do actually like programs to look ‘nice’.

                          So I expanded my idea and realized that timers wouldn’t be needed if you ran your big work in another thread. You can then have your dialog thread sleep most of the time. This progress bar had only 1 second slowdown on my mimic code and thus I consider it to be quite usable in high crunch programs.

                          It also demonstrates a simple thread, critical sections, and a rather simple way to draw a progress bar.

                          This example is clean, but not that well commented. If any question or comments please ask here or email me. Also email me if you would like the .bas file instead of trying to copy this off of the forum.

                          Colin Schmidt
                          Praxis Enterprises, Canada

                          Code:
                          'posted by Colin Schmidt of Praxis Enterprises
                          'any questions email: [email protected]
                          
                          #COMPILE EXE
                          #REGISTER NONE
                          #INCLUDE "win32api.inc"
                          
                          GLOBAL glStatus AS LONG PTR 'Share status with main thread. Slower than local. Use it little.
                          GLOBAL glStatusEnd AS LONG 'Share count-to value with the main thread.
                          GLOBAL csStatus AS CRITICAL_SECTION 'Critical Section protecting glStatus and glStatusEnd
                          
                          GLOBAL ghDlgMain AS LONG
                          %ghDlgMain_Btn = 1
                          %ghDlgMain_Static = 101
                          %ghDlgMain_Status = 41
                          %ghDlgMain_SpeedBarBack = 51
                          %ghDlgMain_SpeedBarFront = 52
                          
                          FUNCTION thrdMyBigCalcs(BYVAL x AS LONG) AS LONG
                              'This thread will *mimic* timing to the ARC4 function in the PB source code forum
                              LOCAL lCount1 AS LONG
                              LOCAL lDoUpdate AS LONG
                              LOCAL lUpdateCount AS LONG
                              STATIC lStatus AS LONG
                              LOCAL p AS BYTE PTR
                              LOCAL c AS LONG
                              LOCAL b AS STRING
                          
                              b = SPACE$(10485760) '10mb string to *mimic* arc4 on
                              p = STRPTR(b)
                          
                              EnterCriticalSection csStatus
                                  glStatusEnd = 10485760
                                  glStatus = VARPTR(lStatus)
                              LeaveCriticalSection csStatus
                              
                              lDoUpdate = glStatusEnd / 100
                              
                              FOR lCount1 = 0 TO LEN(b)-1
                                  
                                  IF lUpdateCount = lDoUpdate THEN
                                      lUpdateCount = 0
                                      EnterCriticalSection csStatus
                                          lStatus = lCount1
                                      LeaveCriticalSection csStatus
                                  END IF
                                  INCR lUpdateCount
                                  
                                  c = @p[lCount1]
                                  c = (c + 1) MOD 256
                                  c = (c + c) MOD 256
                                  SWAP c, c
                                  c = (c + c) MOD 256
                                  c = c
                                  c = c XOR c
                                  INCR c
                              NEXT lCount
                          
                              FUNCTION = %True
                          
                          END FUNCTION
                          
                          CALLBACK FUNCTION cbDlgMain_Btn
                              DIALOG END ghDlgMain
                          END FUNCTION
                          
                          FUNCTION PBMAIN
                              LOCAL lCount1 AS LONG
                              LOCAL lCheck AS LONG
                              LOCAL lStatus AS SINGLE, lStatusEnd AS SINGLE
                              LOCAL lStatusLast AS LONG, lStatusSize AS LONG
                              LOCAL lDlgx AS LONG, lDlgy AS LONG
                              LOCAL lThreadID AS LONG
                          
                              DIALOG NEW 0, "Multi-Threaded Speedbar", , , 200, 60 TO ghDlgMain
                          
                              CONTROL ADD LABEL, ghDlgMain, %ghDlgMain_Static, "Status:", 5, 5, 25, 8
                              CONTROL ADD LABEL, ghDlgMain, %ghDlgMain_Status, "0%", 35, 5, 50, 8
                              CONTROL ADD FRAME, ghDlgMain, %ghDlgMain_SpeedBarBack, "", 10, 15, 179, 14, , %WS_EX_WINDOWEDGE
                              CONTROL ADD LINE, ghDlgMain, %ghDlgMain_SpeedBarFront, "", 12, 21, 0, 5, %SS_BLACKRECT
                          
                              DIALOG SHOW MODELESS ghDlgMain
                              'Get the form all drawn out and looking nice before we start
                              'having the delay between DIALOG DOEVENTS
                              FOR lCount1 = 1 TO 10: DIALOG DOEVENTS: NEXT lCount1
                          
                              InitializeCriticalSection csStatus
                              EnterCriticalSection csStatus
                                  glStatus = VARPTR(lStatus)
                              LeaveCriticalSection csStatus
                          
                              THREAD CREATE thrdMyBigCalcs(%NULL) TO lThreadID
                              DO
                                  'Could be many messages after wait, try to cover them all
                                  'If only one DOEVNTS then progress bar may 'skip'
                                  DIALOG DOEVENTS: DIALOG DOEVENTS: DIALOG DOEVENTS: DIALOG DOEVENTS
                                  SLEEP 100
                          
                                  EnterCriticalSection csStatus
                                      lStatus = @glStatus
                                      lStatusEnd = glStatusEnd
                                  LeaveCriticalSection csStatus
                          
                                  IF lStatusLast <> INT((lStatus / lStatusEnd * 100)) THEN
                                      lStatusLast = MIN(INT((lStatus / lStatusEnd * 100)), 100)
                                      CONTROL SET TEXT ghDlgMain, %ghDlgMain_Status, FORMAT$(lStatusLast, "##%")
                                      lStatusSize = (lStatusLast / 100) * 174
                                      CONTROL SET SIZE ghDlgMain, %ghDlgMain_SpeedBarFront, lStatusSize, 5
                                  END IF
                          
                                  THREAD STATUS lThreadID TO lCheck
                              LOOP WHILE lCheck = &H103
                          
                              CONTROL SET TEXT ghDlgMain, %ghDlgMain_Status, FORMAT$(100, "##%")
                              CONTROL SET SIZE ghDlgMain, %ghDlgMain_SpeedBarFront, 174, 5
                          
                              THREAD CLOSE lThreadID TO lCheck
                              IF lCheck = %False THEN
                                  MSGBOX "Error returned from BigCalcs thread", , "Speedbar"
                              END IF
                          
                              DeleteCriticalSection csStatus
                          
                              CONTROL ADD BUTTON, ghDlgMain, %ghDlgMain_Btn, "&Close", 150, 40, 40, 14 CALL cbDlgMain_Btn
                              DO
                                  DIALOG DOEVENTS
                                  SLEEP 100
                                  DIALOG GET SIZE ghDlgMain TO lDlgx, lDlgy
                              LOOP WHILE lDlgx
                          
                          END FUNCTION
                          [This message has been edited by Colin Schmidt (edited February 05, 2001).]

                          Comment


                          • #14
                            Ah, well why not just call AmtChange = 100 then, 1 x 100 is 100

                            But it's good to go now, it's only calling 100 times Got the percentage down close on compiling and encrypting, decompiling and decrypting is another story but I'm working on it !!

                            As for the code, it is in a separate thread, here's how I did it, works quick too..

                            Code:
                            Notice the modeless dialog box, it does most of hte work, the modal dialog box just displays results:
                            
                            Function FileProcessDialog() As Long
                            'Create visual dialog
                            Dialog New hDlg, g_szCCS & " " & g_szMine & " " & g_szVer  ,,, 250,90 ,  %SW_SHOWNORMAL To pDlg
                            Dialog Send pDlg, %WM_SETICON, %ICON_SMALL, hIcon
                            Control Add Label, pDlg,%FILECOPYLABEL1, "Compressing..",5,1,180,10
                            Control Add Label, pDlg,%FILECOPYLABEL2, g_Files(1), 5,15,125,10
                            Control Add Label, pDlg,%FILECOPYLABEL3, "Total progress", 5,40,55,10
                            Control Add "msctls_progress32",pDlg,%PROGRESS1,"",5,25,185,12, %WS_CHILD Or %WS_VISIBLE Or %WS_CLIPSIBLINGS Or %CCS_BOTTOM
                            Control Add "msctls_progress32",pDlg,%PROGRESS2,"",5,50,185,12, %WS_CHILD Or %WS_VISIBLE Or %WS_CLIPSIBLINGS Or %CCS_BOTTOM
                            Control Add Button, pDlg, %FILECOPYIDCANCEL, "&Cancel", 200,50,40, 14, %WS_TABSTOP
                            Control Add Image, pDlg, %PROGRESSIMAGE,"#1024",205,5,20,20
                            
                            
                            If IsFalse g_lngInitThreadHandle Then
                               Thread Create InitThread(id) To g_hThread
                               ' Let the thread end when it stops
                               Thread Close g_hThread To g_Result
                            Else
                               Exit Function
                            End If
                            
                            'Create modeless dialog for thread:
                            Dialog New pDlg,"" ,,,180,60,  %WS_CHILD Or %DS_CONTROL, 0 To tDlg
                            Dialog Show Modeless tDlg Call ThreadItemsProc
                            Dialog Show Modal pDlg Call pDialogProc
                            
                            End Function  
                            
                            
                            '--------------------------
                            
                            
                            CallBack Function pDialogProc() As Long
                            Local lLoop     As Long
                            
                            Select Case CbMsg
                                Case %WM_CREATE
                                Case %WM_INITDIALOG
                                    MousePtr 11 'Busy
                            
                                Case %WM_COMMAND
                                  Select Case LoWrd(CbWparam)
                                         Case %FILECOPYIDCANCEL
                                            For lLoop = 1 To g_FileIndex
                                                Kill GetWindowsTempDir & Dir$(g_Files(lLoop))
                                            Next
                                            Kill g_Temp
                                            Kill g_OutputEXE
                                            Dialog End tDlg, 0
                                            Dialog End pDlg,0
                                  End Select
                                Case %WM_DESTROY
                                    MousePtr 0
                            End Select
                            End Function   
                            
                            '----------------------------------------------------------------------------------------------------------------
                            
                            Function InitThread(ByVal x As Long) Export As Long
                            Do the dirty work in here
                            Function = %TRUE
                            End function
                            
                            
                            '----------------------------------------------------------------------------------------------------------------
                            
                            CallBack Function ThreadItemsProc() As Long
                            'Control Send CbHndl,%IDAPPLY,%BM_CLICK, 0, 0
                            
                              Select Case CbMsg
                                Case %WM_ACTIVATE
                            
                                Case %WM_COMMAND
                            
                                  Select Case LoWrd(CbWparam)
                                    Case %IDCANCEL
                                        Dialog End tDlg, 0
                                        Dialog End pDlg, 0
                            
                                  End Select
                              End Select
                            End Function
                            
                            '----------------------------------------------------------------------------------------------------------------
                            ------------------
                            Scott
                            mailto:[email protected][email protected]</A>



                            [This message has been edited by Scott Turchin (edited February 04, 2001).]
                            Scott Turchin
                            MCSE, MCP+I
                            http://www.tngbbs.com
                            ----------------------
                            True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                            Comment


                            • #15
                              A really quick smooth ProgressBar can be easily constructed out
                              of an edit control.
                              Update the "progressbar" FillRect().


                              [This message has been edited by Ron Pierce (edited February 04, 2001).]

                              Comment


                              • #16
                                I think this thread affords an opportunity to explain an important
                                concept about Windows programming version DOS programming.

                                In DOS apps it is quite common to display a counter when a long action
                                takes place. For example, maybe a Report engine is reading records
                                of a file which takes awhile to do, so the program displays a counter
                                somewhere on the screen (ie. READING RECORD NUMBER : ####).

                                This rarely slowed down a program !

                                Why ?

                                The reason is that DOS being text based, it only required a few Bytes
                                to be sent to the Video adapter to print the Counter text out. A single
                                character only requires 2 Bytes in text mode, so at most you are
                                sending 10 to 14 Bytes to display the record number for each Iteration.

                                Now, when moving to Windows, DOS programmers tend to use old habits
                                and they simply use a Windows control to display a Text counter for
                                each iteration and they think it shouldn't slow things down very much.

                                Rule #1: Windows Text Display takes at least 100 to 500 times longer than DOS !

                                A single character in DOS only requires 2 Bytes to be sent to the
                                Video Adapter.

                                In Windows the System Font is 8 x 16 pixels in size, which means that
                                a single Character will require 128 Bytes to be sent to the Video Adapter
                                (if in 256 color mode). If the Graphics mode is True Color (24 bit)
                                then it will require 384 Bytes be sent to the Video Adapter.

                                Now here is where it gets really bad !

                                DOS can simply POKE the character Bytes in RAM (very fast).

                                Windows has to send Bytes to the Video Adapter via API functions
                                that may have many levels before the data actually gets to the Video
                                Adapter. Windows does things like Clipping, etc, that slow things down.

                                Before you are done, Windows may have to execute hundreds of bytes of
                                machine code to send hundreds of bytes of pixels values, just to display
                                a single 5 character number for your counter.

                                What this means is that in a worse case senario, I would estimate that
                                Windows display of text could end up taking as much as a 1000 times
                                longer than similiar DOS text display !


                                Now if it takes so long to display text in Windows, imagine how much this
                                would slow down your app, if your app attempted to display a new
                                text string for every iteration of say 5000 to 10000 iterations.




                                ------------------
                                Chris Boss
                                Computer Workshop
                                Developer of "EZGUI"
                                http://cwsof.com
                                http://twitter.com/EZGUIProGuy

                                Comment


                                • #17
                                  BUT the only thing that slows down my example above is that a single LONG global is needed for the counter in order to share the progress with the main thread. By removing the code that updates the progress bar and the text label in the main thread the time did not drop one measurable bit.

                                  However, I have edited the code again to remove all but one reference to this global in the loop and only update this global 100 times. The performance loss in the “speed critical” loop in this example was only one second after 10mb of ARC4 mimic. A program user could never tell the difference without a stopwatch.

                                  Colin Schmidt

                                  ------------------
                                  Colin Schmidt & James Duffy, Praxis Enterprises, Canada
                                  [email protected]

                                  Comment


                                  • #18
                                    I did the stopwatch thing

                                    Now, my RC4 code is en crypting a buffer already in memory, file has long been read and won't be written for a long time still..


                                    With progress bars, 5 megs took about 10 seconds.

                                    And you won't believe this but that same 5 megs took 3.2 seconds without the progress bars...


                                    Needless to say the progress bars are gone

                                    A happy little label that says "Please wait" replaced it.

                                    Scott

                                    ------------------
                                    Scott
                                    mailto:[email protected][email protected]</A>
                                    Scott Turchin
                                    MCSE, MCP+I
                                    http://www.tngbbs.com
                                    ----------------------
                                    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                                    Comment


                                    • #19
                                      Colin;

                                      Your use of Threads does prevent your iterated calculation code from
                                      slowing down by the repaints of the progress bar.

                                      You do have to remember though that what I said still applies to
                                      code running in the same thread. Your code does not demonstrate
                                      that the display of a control isn't slow. It simply demonstrates
                                      running critical iterated code in a thread prevents it from being
                                      slowed down by the repainting of controls. Technically, your code
                                      is runnning two separate loops. One inside the thread for calculations
                                      and another in the PBMAIN procedure which is attempting to repaint
                                      a control as fast as it can. The loop in PBMAIN will not iterate as
                                      many times as the one in the thread. The loop in PBMAIN will iterate
                                      only as fast as the video adapter (and CPU) can keep up with repaints.

                                      While the use of threads is very useful in such situations, it must
                                      also be remembered that using threads adds a greater level of
                                      complexity to ones program. Debugging problems with Threads can be
                                      difficult and one must be very careful when using threads
                                      to make sure you terminate it correctly.

                                      Also threads can create problems when calling external functions. You
                                      must make sure that all functions (either in your app or externally in
                                      external DLLs) are thread safe, before using them from a thread.

                                      I would be very wary of calling third party DLLs (ie. SQL) from a
                                      Thread unless I was using absolutely only one thread.

                                      In summary, Threads are an excellent workaround, but they must be
                                      viewed with caution. The use of Threads though doesn't prove my
                                      point made as wrong though. Iterated updates of any Windows control
                                      can slow things down significantly, simply because of the graphic
                                      nature of Windows. Displaying even just text is not the same as it
                                      is in DOS.


                                      ------------------


                                      [This message has been edited by Chris Boss (edited February 05, 2001).]
                                      Chris Boss
                                      Computer Workshop
                                      Developer of "EZGUI"
                                      http://cwsof.com
                                      http://twitter.com/EZGUIProGuy

                                      Comment


                                      • #20
                                        Actually, the code with a thread dedicated to update a progress bar will
                                        run slower than updating the progress bar in the same thread which performs
                                        the data processing - unless you are running under NT (or some flavour of Windoze 2000
                                        which supports SMP) and you have a system with multiple processors.

                                        Context switching will cause the code to be slower. Switching threads introduces overhead
                                        and increases the number of cpu cycles required to perform all the desired operations.

                                        I can not envision 100 updates to a progress bar taking as long as Scott has measured.
                                        Apparently, his code is using more updates than 100.

                                        Create a Progress bar using an edit control and I know you will not be adding measurable
                                        overhead in 100 updates. I performed 10,000 updates to mine in less than 100ms on a
                                        lowly mmx233.




                                        ------------------
                                        Ron

                                        Comment

                                        Working...
                                        X