Page 2 of 2
Re: Progress Bar Control Performance Testing
Posted: Thu Feb 07, 2019 8:53 pm
by ljubacirovic
Hello Marek,
I am certain that your conceptual solution is OK for displaying of indexing flow. I am just wandering if you tested it on a live data and how much processing overhead it produces taking in the account that for every nStep records during indexing it calls Eval -> NtxProgress() -> do events. I am afraid that it may be very time consuming.
Best regards,
Ljuba
Re: Progress Bar Control Performance Testing
Posted: Thu Feb 07, 2019 9:13 pm
by mol
I had no time to test.
My application reindexes data only in critical situation, so it's not big problem to wait
Re: Progress Bar Control Performance Testing
Posted: Thu Feb 07, 2019 9:34 pm
by andyglezl
Quizà de esta manera, simulando la animaciòn de que està trabajando hasta que termine el proceso completo.
*----------------------------------------------------------------------------------------------------------------------------
Maybe in this way, simulating the animation you're working on until the entire process is finished.
http://www.hmgforum.com/viewtopic.php?f ... BAR#p56274
Re: Progress Bar Control Performance Testing
Posted: Fri Feb 08, 2019 7:01 am
by ljubacirovic
Hello Andrés,
Yes, your example is OK for the processes where you do not know how long will they take to finish (as the ENABLE MARQUEE is intended for). For example, when application waits response from some source (process, service, server, database, etc.) other than user. But, when you have to conduct some local processing in the previously known number of steps, records or whatsoever value you take as a measurement, then it is very informative to have a counter at least to show the progress. Progress bar is a fancier but more resource consuming way to achieve this. I just tried to point to the overhead/cost of implementing graphical progress control in such a situation. I think that users do not need a nice looking interface which makes them wait 10 times longer than necessary to complete some mundane task. My goal is to balance usability/performance and GUI gadgets.
Ljuba
Re: Progress Bar Control Performance Testing
Posted: Fri Feb 08, 2019 3:42 pm
by andyglezl
Claro que se puede modificar y adaptar a diferentes necesidades,
por ejemplo:
En vez de utilizar ENABLE MARQUEE, se puede crear un LABEL donde
se esté desplegando el valor correspondiente al contador que quieras llevar.
+----------------------------------------------------------------------------------------------
Of course, it can be modified and adapted to different needs,
for example:
Instead of using ENABLE MARQUEE, you can create a LABEL where
the value corresponding to the counter you want to carry is being displayed.
Re: Progress Bar Control Performance Testing
Posted: Fri Feb 08, 2019 8:08 pm
by ljubacirovic
Hello Andrés,
Obviously you have not noticed the code within my original post that I used to compare performances of progress bar versus label. Anyway, I appreciate your interest for the topic.
Ljuba
Re: Progress Bar Control Performance Testing
Posted: Sat Feb 09, 2019 2:14 am
by andyglezl
Pongo a su consideración lo siguiente...
*-------------------------------------------------------
I put to your consideration the following ...
Code: Select all
#include 'hmg.ch'
PROCEDURE ProgTest
/*
*/
PRIVATE cProgCh
SET CODEPAGE TO ENGLISH
cProgCh := chr(254)
DEFINE WINDOW wProgTest ;
AT 10, 10 ;
WIDTH 420 HEIGHT 250 ;
TITLE "Progress Indicator Testing" ;
ICON NIL CHILD CURSOR NIL ;
ON INTERACTIVECLOSE NIL ;
ON GOTFOCUS NIL ;
ON LOSTFOCUS NIL
DEFINE LABEL lbSteps
PARENT wProgTest
ROW 20
COL 10
VALUE "Enter number of steps for the test loop"
WIDTH 220
HEIGHT 20
END LABEL
DEFINE TEXTBOX tbSteps
PARENT wProgTest
ROW 18
COL 250
HEIGHT 20
VALUE 10000
WIDTH 100
INPUTMASK '999,999,999'
FORMAT 'E'
MAXLENGTH 9
DATATYPE NUMERIC
MAXLENGTH 9
ONGOTFOCUS wProgTest.tbSteps.CaretPos := 8
ONENTER wProgTest.btExecute.SetFocus
RIGHTALIGN .T.
VISIBLE .T.
TABSTOP .T.
END TEXTBOX
DEFINE CHECKBOX cbProgBar
PARENT wProgTest
ROW 80
COL 10
CAPTION 'Progress bar'
VALUE .F.
WIDTH 100
HEIGHT 20
TOOLTIP 'Check if you want to test progress bar as progress indicator.'
VISIBLE .T.
TABSTOP .T.
END CHECKBOX
DEFINE PROGRESSBAR pbFlow
ROW 80
COL 110
WIDTH 270
HEIGHT 20
RANGEMIN 1
RANGEMAX 100
VALUE 1
TOOLTIP ""
HELPID Nil
VISIBLE .f.
VERTICAL .F.
END PROGRESSBAR
DEFINE CHECKBOX cbLablBar
PARENT wProgTest
ROW 100
COL 10
CAPTION 'Label bar'
VALUE .F.
WIDTH 100
HEIGHT 20
TOOLTIP 'Check if you want to test label as progress indicator.'
VISIBLE .T.
TABSTOP .T.
END CHECKBOX
DEFINE LABEL lbFlow
PARENT wProgTest
ROW 100
COL 110
VALUE ""
WIDTH 10
HEIGHT 50
FONTCOLOR {0,76,153}
END LABEL
DEFINE BUTTON btExecute
ROW 180
COL 110
WIDTH 200
HEIGHT 25
ACTION {TestInd(), wProgTest.tbSteps.SetFocus}
CAPTION "Execute"
TOOLTIP "Accept entered parameters and execute test."
TABSTOP .T.
VISIBLE .T.
END BUTTON
END WINDOW
wProgTest.tbSteps.SetFocus
wProgTest.Center
wProgTest.Activate
RETURN NIL
//*---->
FUNCTION TestInd
/*
*/
nKfLb := 0
nSteps := wProgTest.tbSteps.Value
nStart:= SECONDS()
IF wProgTest.cbProgBar.Value
cTest := wProgTest.cbProgBar.Caption+' as progress indicator'
wProgTest.pbFlow.RangeMax := nSteps
wProgTest.pbFlow.Visible := wProgTest.cbProgBar.Value
ELSEIF wProgTest.cbLablBar.Value
cTest := wProgTest.cbLablBar.Caption+' as progress indicator'
wProgTest.lbFlow.Visible := wProgTest.cbLablBar.Value
wProgTest.lbFlow.Width := wProgTest.Width-wProgTest.lbFlow.Col
nKfLb := (wProgTest.lbFlow.Width/wProgtest.lbFlow.FontSize)/105
ELSE
cTest := 'Without progress indicator'
END
wProgTest.pbFlow.RangeMax := nSteps //*************************** ADD THIS
*wProgTest.pbFlow.RangeMax := ALIAS->(lastrec()) // Define the number of total steps
FOR nI := 1 TO nSteps
IF RIGHT( STR(nI,6), 1) = "0" //*************************** ADD THIS // show every 10 steps
IF wProgTest.cbProgBar.Value
IF nI==wProgTest.pbFlow.RangeMax
* wProgTest.pbFlow.RangeMax := wProgTest.pbFlow.RangeMax + 1 //*************************** COMMENT THIS
wProgTest.pbFlow.Value := nI // + 1 //*************************** COMMENT THIS
* wProgTest.pbFlow.RangeMax := wProgTest.pbFlow.RangeMax - 1 //*************************** COMMENT THIS
ELSE
wProgTest.pbFlow.Value := nI + 1
ENDIF
wProgTest.pbFlow.Value := nI
ELSEIF wProgTest.cbLablBar.Value
nRatio := INT((nI/nSteps)*100)
wProgTest.lbFlow.Value := REPLICATE(cProgCh,INT(nRatio*nKfLb))+' '+LTRIM(STR(nRatio))+'%'
END
ENDIF //*************************** ADD THIS
/*
*************** Más el tiempo que se tarde en hacer cualquier proceso...
*************** Plus the time it takes to do any process...
*************** Append, Replace, Delete, etc., etc.
*/
DO EVENTS
NEXT
MsgInfo(cTest+' -> '+LTRIM(STR(SECONDS() - nStart))+ " seconds",'TEST DURATION')
wProgTest.pbFlow.Visible := wProgTest.cbProgBar.Value := .F.
wProgTest.lbFlow.Visible := wProgTest.cbLablBar.Value := .F.
wProgTest.btExecute.Caption := "Execute"
RETURN NIL
//*---->
Re: Progress Bar Control Performance Testing
Posted: Sat Feb 09, 2019 5:42 pm
by ljubacirovic
Hello Andrés,
Thank you on your suggestions, I reviewed and tested them.
What I liked is the idea to shorten the IF statement within the loop. At first, I thought it would cause problems in displaying progress bar control under Aero theme. But at my utter joy it worked. So I changed the condition to < instead of == and removed FOUR lines of code. It did not speed up the process but the code is simpler/shorter now.
Also, I introduced nQt := 100/nSteps and put it before loop so there is one calculation less per step.
====> UPDATE !!!
After more thorough testing of this shortened IF construct I realized that it does not perform as expected. That is, progress bar fills up AFTER the message of the process completion is displayed. Therefore, I discarded the shortened IF construct and reversed to the original one. Only then progress bar fills up BEFORE the message of the process completion is displayed. Unfortunately, my first hunch was correct.
<==== UPDATE !!!
I would like to remind you of the value limitation for RangeMax which is set to two bytes in HMG (max 65,535) although Windows documentation says that Windows progress bar accepts 32 bit value for RangeMax. I suppose that some C modul of HMG needs to be modified and recompiled. Therefore, I would not recommend you to set RangeMax to nSteps when nSteps maximum input value is set to 999,999,999!
Now, the purpose of this test is to compare execution speeds, step by step, under the same conditions, for two different ways of displaying progress. Introducing technique to skip 10 steps is not in line with the purpose of the test, because it would yield some dubious performance results. Also, there is a simpler way to check if the number ends with "0" using the modulus operator IF nX%10 == 0. I believe that you overlooked it in your eagerness.
Here is the modified code.
Code: Select all
FUNCTION TestInd
/*
*/
nKfLb := 0
nSteps := wProgTest.tbSteps.Value
nStart:= SECONDS()
IF wProgTest.cbProgBar.Value
cTest := wProgTest.cbProgBar.Caption+' as progress indicator'
wProgTest.pbFlow.RangeMax := 100
wProgTest.pbFlow.Visible := wProgTest.cbProgBar.Value
ELSEIF wProgTest.cbLablBar.Value
cTest := wProgTest.cbLablBar.Caption+' as progress indicator'
wProgTest.lbFlow.Visible := wProgTest.cbLablBar.Value
wProgTest.lbFlow.Width := wProgTest.Width-wProgTest.lbFlow.Col
nKfLb := (wProgTest.lbFlow.Width/wProgtest.lbFlow.FontSize)/105
ELSE
cTest := 'Without progress indicator'
END
nQt := 100/nSteps //<== This a new variable, quotient for percentage recalculation.
nI := 0
while ++nI<=nSteps //<== DO WHILE ... END DO loop instead of FOR ... NEXT loop
nRatio := INT(nI*nQt) // <== Simplified calculation within loop
IF wProgTest.cbProgBar.Value
/*
IF nRatio<wProgTest.pbFlow.RangeMax // <== Modified condition and simplified IF ... ENDIF block. ==>DISCARDED
wProgTest.pbFlow.Value := nRatio + 1
ENDIF
*/
IF nRatio==wProgTest.pbFlow.RangeMax // <== Original IF ... ENDIF block, ensures that progress bar is filled up BEFORE the message
// of the process completion is displayed.
wProgTest.pbFlow.RangeMax := wProgTest.pbFlow.RangeMax + 1
wProgTest.pbFlow.Value := nRatio + 1
wProgTest.pbFlow.RangeMax := wProgTest.pbFlow.RangeMax - 1
ELSE
wProgTest.pbFlow.Value := nRatio + 1
ENDIF
wProgTest.pbFlow.Value := nRatio
ELSEIF wProgTest.cbLablBar.Value
wProgTest.lbFlow.Value := REPLICATE(cProgCh,INT(nRatio*nKfLb))+' '+LTRIM(STR(nRatio))+'%'
END
wProgTest.btExecute.Caption := 'Step '+LTRIM(STR(nI))+' of '+LTRIM(STR(nSteps))
DO EVENTS
end
MsgInfo(cTest+' -> '+LTRIM(STR(SECONDS() - nStart))+ " seconds",'TEST DURATION')
wProgTest.pbFlow.Visible := wProgTest.cbProgBar.Value := .F.
wProgTest.lbFlow.Visible := wProgTest.cbLablBar.Value := .F.
wProgTest.btExecute.Caption := "Execute"
RETURN NIL