Jump to content
dkjMusic

App is faster in IDE

Recommended Posts

I am deveoping an app in Delphi 10.3 Community Edition. At one point the program retrieves equation parameters from a MS Access datbase and calculates x's and y's for a set of plots. It does this to produce 15 TCharts with 9 line series each.

 

I have found that these operations often take much longer to execute when I run the standalone app as compared to running the app in the IDE. Below is a table of execution times (using GetTickCOunt). The columns are TChart graph #, milliseconds in the IDE, and milliseconds for standalone.

 

 #    IDE     SA
--    ---  -----  
 1    703  14890
 2    875    500
 3    844  14828
 4    829  14844
 5    875    468
 6    812    500
 7    906  14859
 8   1281  14813
 9    938  14860
10    829  14875
11  15562  14844 
12    937  14859
13    927  14860
14    812    531
15    828  14868

 

What could explain the differences in execution times and what can I do to decrease the times for the standalone execution?

Share this post


Link to post

This, I believe, is due to the fact that the IDE developers, in order to keep the huge amount of threads, timers, etc. needed by the development environment more responsive, have forced the Windows timeCAPS down from the default values (about 50ms) to the lowest possible values, so as to achieve greater accuracy in the timers.

Some time ago I wasted a lot of hours on this myself.
I used to run a program from IDE and it was faster than when IDE was not active in memory. As long as it was active, any program would run better, even if not launched from it.

From here I realized that the IDE was changing something in the operating system.
I tried to make a program that read timeCAPS with IDE active (they are system and not process) and with IDE active it gave me 1ms, without IDE active 50ms 🙂

In my applications I force too, obtaining the same times (precision) of timeGetTime and GetTickCount or precision in TThread.Sleep when I run WITH IDE in run o without IDE:

uses
	MMSystem;

; use this option to disable the force of timer precision
{$DEFINE USES_TIME_BEGIN_END_PERIOD}

var
{$IFDEF USES_TIME_BEGIN_END_PERIOD}
  TimeCaps: TTimeCaps;
  NeedToChangeTimerPrecsion: Boolean;
{$ENDIF}
  ... other global values


procedure PrecisionTimersStart:
begin
{$IFDEF USES_TIME_BEGIN_END_PERIOD}
    // starts high precision timer
    if timeGetDevCaps(@TimeCaps, SizeOf(TTimeCaps)) = TIMERR_NOERROR then
      NeedToChangeTimerPrecsion := timeBeginPeriod(TimeCaps.wPeriodMin) = TIMERR_NOERROR;
{$ENDIF}
end;

procedure PrecisionTimersEnd:
begin
{$IFDEF USES_TIME_BEGIN_END_PERIOD}
    // stops high precision timer
    if NeedToChangeTimerPrecsion then
      timeEndPeriod(TimeCaps.wPeriodMin);
{$ENDIF}
end;


Just call PrecisionTimersStart at program START, eg in dpk code, and call PrecisionTimersStop when the program ends.

Edited by shineworld

Share this post


Link to post

If the runtime chart has clickable points perhaps its binding them at runtime.  I run 6 Teecharts with 6 to 8 Lines 400 points or more plus legend updating with latency ~ 5ms. 

 

What's interesting for a real time teechart when made visible, the memory size as the app increases to 1.5 megs 32bit and to 3 megs for 64 bit so 6 Teecharts if each is shown increase a 12 meg program to 40 ish. So there must be some lazy loading of UI parts going on.   On win11 the app reported size shrinks in twenty or so minutes.

Share this post


Link to post
22 hours ago, Pat Foley said:

If the runtime chart has clickable points perhaps its binding them at runtime.  I run 6 Teecharts with 6 to 8 Lines 400 points or more plus legend updating with latency ~ 5ms. 

 

What's interesting for a real time teechart when made visible, the memory size as the app increases to 1.5 megs 32bit and to 3 megs for 64 bit so 6 Teecharts if each is shown increase a 12 meg program to 40 ish. So there must be some lazy loading of UI parts going on.   On win11 the app reported size shrinks in twenty or so minutes.

Pat, I have  FamilyCurve.ClickableLine := False;  for each line series.

 

21 hours ago, Arnaud Bouchez said:

To be fair, there is a 14,000 time addition on both sides, more often outside of the IDE.

 

Something is interfering with your application, and wait for 14 seconds.

 

Don't guess, use a profiler. You will see where the time is spent.

For instance a good one is https://www.delphitools.info/samplingprofiler/

I ran the SamplingProfiler and, lo and behold, I did not see the 14-second delay for any of the graphs.

What could this mean?

Arnaud, please disregard this. I just reran the SamplingProfiler again and saw the same delays.

Edited by dkjMusic

Share this post


Link to post

shineworld, I just tried your approach and there were still significant delays in some of the graphs.

I have no idea what to try next.

Share this post


Link to post

Having no code shared, I am just speculating that you update data while all 15 charts are visible on the screen.

If that is the case, you might try to fill data while charts are hidden. You might want to fill your data between begin/end update statements

  Chart1.SeriesGroups.BeginUpdate();
  // data fill here
  Chart1.SeriesGroups.EndUpdate();

 

It is just a wild guess and I am not sure if this is the problem. You should at least have detailed debug logging for yourself with milliseconds accuracy to understand if it is reading from the database is slow or filling up the chart data or something else.

Share this post


Link to post
2 hours ago, dkjMusic said:

Pat, I have  FamilyCurve.ClickableLine := False;  for each line series.

Could you set all the Teecharts.visible to False, then measure the effects of showing each Teechart in Runtime. Or switch the data source in IDE and measure that to determine if data is being cached in the IDE.  You could use a client data set to help cache the data into the executable, so you don't need to reload.   

Share this post


Link to post
2 hours ago, dkjMusic said:

Arnaud, please disregard this. I just reran the SamplingProfiler again and saw the same delays.

you could still put some explicit logging into your application to see where this 14 seconds delay is coming from instead of guessing

 

Share this post


Link to post

Sounds like file locking given that you are using MSAccess as the DB.  My 2 suspects are connection deadlock or virus scanner locking the database.

 

How many query components do you have on the form? Are they all set to connect at startup? If this is Firedac, use FDMonitor to trace activity and see where the delay is.

 

Start simple, open Task Manager and observe cpu and disk activity. What process is at the top of CPU consumption.  If the system is idle cpu and idle disk then it is waiting for something to timeout.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×