はじめに
みなさんプロファイリングしてますか?
MQL4のIDEにはプロファイリング機能が備わっているので使ってみましょう
(プロファイリングで設計が間違っていたことに気がついて改修するので暇つぶしで書いてます。。)
経緯
やってみればわかりますが、大抵のプログラムはロジックの部分がボトルネックになっているはずです。
特に
iRSI(...)
とかiCustom(...)
とかのi系関数
は厄介です。
ロジックが複雑になればなるほどこれらの関数の呼び出し回数が増え、コストが馬鹿にならなくなります。
対処
基本的な対応は変数に格納してしまうことです。関数の呼び出しはコストが高いからです。
例)
double a;
string SYMBOL = Symbol();
int PERIOD = Period();
double ret;
a = iRSI(SYMBOL, PERIOD, 2, PRICE_CLOSE, 0);
for (int i=0; i<1000; ++i){
ret += a;
}
string SYMBOL = Symbol();
をグローバルで宣言するとSymbol()関数の呼び出し回数が減って高速化が図れるわけですね。
Symbol()を変数に格納して使用することで測定値で約1.5倍の速度になりました。
では他の記述方法ではどうか
例えばiRSI関数の引数はこんな感じですが
iRSI(symbol, timeframe, period, applied_price, shift)
第1引数は次の4通り
- NULL
- Symbol()
- SYMBOL ← 変数に格納したSymbol()
- "USDJPY"
第2引数は次の5通り
- NULL
- Period()
- 0
- PERIOD ← 変数に格納したPeriod()
- PERIOD_CURRENT
第3引数は定数なので無関係
第4引数は2通り
- PRICE_CLOSE
- 0 ←対応する実際の数値
第5引数は定数なので無関係
と5x4x2 = 40通りの記述方法があります!
ではどの記述方法が一番速いのか?
結論
プロファイリングの結果を載せようと思いましたが、コピペが面倒なので割愛します。(速い)>(遅い)で書いてます。
Symbol系
"USDJPY" ≒ SYMBOL ≒ NULL >> Symbol()
当然の結果のように思います。Period系
NULL > 0 ≒ PERIOD_CURRENT ≒ PERIOD >> Period()
意外なことにNULLが最も高速でした。applied_price系
0 ≒ PRICE_CLOSE
ほぼ差はありませんでした。
不等号の基準は
- 「>>」: 明確な差があった
- 「>」: 明確な差は無いものの、順位は入れ替わらなかった
- 「≒」: 順位が入れ替わることがあった
です。測定では次のコードを使いまわしてそれぞれ10回ほど回しました。
int cnt = 1000;
int PERIOD = PERIOD_CURRENT;
string SYMBOL = Symbol();
int PRICE_KIND = PRICE_CLOSE;
void a(){
double a;
for (int i=0; i <cnt; ++i){
a = iRSI(SYMBOL, NULL, 2, PRICE_CLOSE, 0);
}
}
void b(){
double b;
for (int i=0; i <cnt; ++i){
b = iRSI(SYMBOL, 0, 2, PRICE_CLOSE, 0);
}
}
void OnStart(){
for (int i=0; i<100; ++i){
a();
b();
}
}