Performance tuning tips

AmiBroker is one of the fastest (if not the fastest) technical analysis program, still the user by applying incorrect settings, poor formula coding and other sub-optimum choices can significantly slow it down. This short chapter we will give few hints on how to make program perform as it was originally designed to.

There are three areas of performance tuning:

  1. Operating system / machine level
  2. AmiBroker settings level
  3. Formula coding

On operating system level you should do:

On AmiBroker settings level

On Formula coding level

Poor formula coding is the foremost reason of slow down. People coming from "other" languages often do not realize the full potential of AFL array processing and code everything "old" style (i.e. with loops). Loops can be 10..50 times slower than equivalent array-based code. So for best speed you should avoid loops at all replacing them with array processing, or at least make looping code as short as possible.

Consider the following code:

SetBarsRequired( sbrAll );

for( i = 0; i<BarCount; i++)
   med[ i ] = (
H[ i ] + L[ i ])/2;

"Loop time: "+GetPerformanceCounter(1);

med = (
H + L )/2;

"Array time: "+GetPerformanceCounter(1);

When running this code on 350000 bars the loop version it takes 100ms (0.1s) to execute loop version and only 2ms (0.002ms) to execute array version (so array code is 50 times faster than looping). The difference is not so significant with less bars, but still with even 300 bars, loop requires 0.1ms and array needs 0.01ms so it is 10 times faster.

So there are few guidelines for AFL coding:

Performance monitoring

In order to help you in real-time monitoring of program performance, AmiBroker provides two tools. First is Performance monitor window, second is Performance indicator that is located on the right most side of the AmiBroker status bar.

The status bar performance indicator shows:

Load Factor is a percentage value that shows relative 'snappiness' of the program. The load factor is calculated as (total chart refresh time in milliseconds)/2 + (total data access time in milliseconds)/2 + (free virtual memory below 20% of total memory available). So it will reach 100% if any of situations listed below happen:

Total chart refresh time is a sum of times needed to redraw completely all charts displayed on screen, it includes AFL execution time for each chart pane and GDI (graphics) output on screen. (It does not include data access)

Total data access time is sum of times required to access fresh data via plugin for all displayed symbols plus time required to apply time filtering, and time compression from base interval to displayed interval.

Plug-in time per symbol is time spent in plug-in GetQuotes call per *single* symbol. If you display 10 symbol charts at once AmiBroker will call GetQuotes 10 times so this time gets multiplied by number of symbols displayed (this total plugin time *is* included in total data access time figure - listed above)
If Plug-in time per symbol exceeds 10ms it means that plugin is slow (or does not use new ADK 2.0), if this is the case you should contact plugin vendor to get updated plugin that uses ADK 2.0.

Recommended is to keep this load factor below 100%. When load factor is 100% AmiBroker is able to keep updating all charts in real-time (more frequently than 5 times per second) and maintain responsive and smooth user-interface. With load factor of 200% AMiBroker is still able to keep updating all charts as frequenty as 2.5 times per second, but user interface reaction time may be impaired a bit. Keeping load at 100% or less is recommended.
200% is maximum value that allows more or less "normal" operation.

When load factor rises above 100% the warning tooltip will pop up once informing what is the reason of poor performance When load factor rises above 300% the above tooltip will reappear every minute.

AmiBroker will continue working with loads even above 1000% however the performance will be bad (one update per 5 seconds or more).

Multithreading performance

For more information about optimum use of multithreading and other general remarks regarding performance see Efficient Use of Multithreading.