Olf   Projects   Art   Software   Bio   Links   Private   Mail
  Deutsche Version

 | Up |

FuncSub

While I was trying to enhance the performance for Geniustrader I noticed that much time is used for various function calls that simply deliver a single value.

This results from the strict objectorientated styls in which GeniusTrader is written. This is quite useful to make the code readable but it leads also to a very bad performance. I show you here the result of a somewhat larger backtest, analyzed with the DProf-module (the DirtyKill-module is applied so that the Carp::Datum calls are eliminated):

Tested ... ok in 79 seconds
Total Elapsed Time = 20.27753 Seconds
         User Time = 14.72753 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 74.2   10.92  7.779 157523   0.0000 0.0000  GT::CacheValues::is_available
 44.9   6.620 11.841 194946   0.0000 0.0001  GT::ArgsTree::get_arg_values
 38.8   5.719  3.816 952019   0.0000 0.0000  GT::Registry::get_name
 37.5   5.529  2.043 174341   0.0000 0.0000  GT::Calculator::indicators
 36.8   5.426  6.158 506514   0.0000 0.0000  GT::Indicators::Prices::calculate
 22.0   3.246  3.968 201000   0.0000 0.0000  GT::Indicators::Generic::Eval::cal
                                             culate
 21.6   3.186  4.358  13517   0.0002 0.0003  GT::Dependency::dependencies_are_a
                                             vailable
 18.7   2.764 17.552   8002   0.0003 0.0022  GT::Indicators::calculate_interval
 9.36   1.379  7.435 163164   0.0000 0.0000  GT::Indicators::__ANON__
 9.23   1.359  3.472  40023   0.0000 0.0001  GT::Dependency::days_required
 9.17   1.350  0.962 193972   0.0000 0.0000  GT::CacheValues::get
 7.99   1.177 24.249   2502   0.0005 0.0097  GT::Indicators::SMA::calculate
 6.65   0.980  0.953  13743   0.0001 0.0001  Carp::Datum::DTRACE
 5.70   0.839  0.847    557   0.0015 0.0015  Carp::Datum::Strip::strip

As one can clearly see, a large part of the runtime is used for the function GT::CacheValues::is_available. This function only returns one value (if a hashelement is defined or not). Because this function is called approx. 160,000 times this leads to a needlessy overhead.

After downloading the script you should copy your GT-directory to /tmp and apply the script on all files:

for i in $(find /tmp/GT -name '*.pm')
do
   cp $i /tmp/funcsub.tmp
   perl funcsub.pl /tmp/funcsub.tmp > $i 
done;

Now simply insert a use lib '/tmp';-statement in the program that you want to execute and you'll get a much better performance (the call to DirtyKill is - in contrast to the listing above not contained in the list):

Tested ... ok in 41 seconds
Total Elapsed Time = 27.65204 Seconds
         User Time = 28.04077 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 18.5   5.199  9.895 194946   0.0000 0.0001  GT::ArgsTree::get_arg_values
 13.3   3.750  3.305 506514   0.0000 0.0000  GT::Indicators::Prices::calculate
 8.56   2.399  2.520 201000   0.0000 0.0000  GT::Indicators::Generic::Eval::cal
                                             culate
 7.91   2.219  2.416  13517   0.0002 0.0002  GT::Dependency::dependencies_are_a
                                             vailable
 6.60   1.852 10.603   8002   0.0002 0.0013  GT::Indicators::calculate_interval
 5.53   1.550  1.356 193972   0.0000 0.0000  GT::CacheValues::get
 5.10   1.430  6.421 163164   0.0000 0.0000  GT::Indicators::__ANON__
 4.28   1.199  4.346  40023   0.0000 0.0001  GT::Dependency::days_required
 3.71   1.040 17.051   2502   0.0004 0.0068  GT::Indicators::SMA::calculate
 3.21   0.899 65.776   6002   0.0001 0.0110  GT::Dependency::compute_dependenci
                                             es
 2.96   0.830  0.671 158817   0.0000 0.0000  GT::ArgsTree::get_nb_args
 2.57   0.720  0.706  13743   0.0001 0.0001  Carp::Datum::DTRACE
 2.50   0.700  0.640  59542   0.0000 0.0000  GT::Dependency::get_indicator_depe
                                             ndencies

The performance is enhanced by nearly 50% ... and I'm sure there are some more functions that can be replaced like this (as always feedback is very welcome).

But you have to pay attention that the script is based on regular expressions only - thus an error can occur quite easily. For the future it would be better to use e.g. B::Deparse to write a real parset that is on the one hand able to find short functions by itself and on the other hand makes it possible to consider the type of the calling object.

The functionality of this module is now integrated in the module OptimizeGT.pm that is now also part of the official distribution.

Download von funcsub.pl


 Fresh stuff  

Gerbils

Xmas Cookies

Tim the bird

Trading Journal V0.10

 Features  

Impressum

Feedback

Newsletter

eCards

Geniustrader

 
 News  

Images out of africa

Back from the island

Sign of life

More pictures, more visitors, more recipes ...

Happy New Year!

More news...

 
© 2004 Oliver Bossert