mql5言語の特徴、微妙なニュアンスとテクニック - ページ 50

 
fxsaber

これは些細な問題です。そうです。コンパイラのオプティマイザは、このような文字列の瞬間を最適化する方法をまだ知らないのです。しかし、遅くなるのは文字列の割り当てが問題なのです。

一次的なものだと思います。文字列の代入を高速化するか、コードから排除するか、どちらが効率的でしょうか?もちろん、文字列の割り当てそのものが必要なケースもありますが、その頻度はどれくらいでしょうか。ほとんどの場合、一時的な変数しか扱わない。

また、これらの文字列演算をどれだけ高速に実装できるかも問題です。まるで何倍も加速できるかのような言い方ですね。そうでしょうか。すでに何度も何度も最適化しすぎているのです。仮にあと20〜30%搾り取れたとしても、何の変化もないでしょう。

ところで、文字列変数を定数として宣言しようとしませんでしたか?

だから、こんな書き方をするのなら

if ((OrderSymbol() == Symb) && (OrderMagicNumber == Magic))

OrderSymbol節は、一般条件の最後に押し込むのがよいでしょう。

まあ、当然ですね。また、OrderSymbolやMQLとは全く関係ありません。文字列操作はそれだけでコストがかかるので、無駄に使わない方がいい。

 

そうして、その間に

fxsaber

例えば、FIBOで1ヶ月間リアルティックを走らせると、約100万ティックになります。毎ティックごとにPositionGetStringの値を取得して何かと比較するのであれば、パフォーマンスは問題ありませんが、最初に関数の結果を文字列変数に代入してから比較すると、実行時間が1秒程度長くなってしまいます。


もし、それが小さなことに思えるなら、それは間違ったビジョンです。このようなEAを最適化モードで数千回実行すると、その1秒は待ち時間の延長になる。例えば、無害な文字列の割り当てが、最適化の際にさらなる待ち時間を発生させることがあります。このニュアンスに注意し、考慮してください。

このやり方が非常に非効率的であることを、ご自身で理解していただきたいと思います。なぜ、各ティックで PositionGetStringを取得する必要があるのでしょうか?そこで何を変えることができるのか。特に、あなた自身がこのポジションを開いたこと、つまり、すべてがあらかじめわかっていることを考えると、なおさらです。

つまり、パフォーマンスの最適化ということであれば、まずはプログラムロジックそのものを最適化する必要があるのです。

 
アレクセイ・ナヴォイコフ

そして、これらの文字列操作をどれだけ高速化できるかも問題です。まるで何倍も加速できるかのような言い方ですね。そうでしょうか。すでに何度も何度も最適化しすぎているのです。たとえ20〜30%多く搾り取ることができたとしても、その差はありません。

その時々で

ところで、文字列変数を定数として宣言してみたことはないのでしょうか?

はい、そうです。
 
アレクセイ・ナヴォイコフ

なぜ毎ティック ごとにPositionGetStringを取得するのか?そこで何が変えられるのか。特に、このポジションを自分で開いたこと、つまり、すべてが事前に分かっていることを考えると、なおさらです。

まあ、性能の最適化ということであれば、まずはプログラムロジック自体を最適化する必要がありますね。

このようなロジックを持つ戦闘ロボット:このような時間間隔ではEURUSDのオープンポジションは存在しないはずです。あれば、それを閉じる。

GBPUSDのオープンポジションを持っています。OrderSymbolを毎ティック確認せずに、上記の条件を満たすにはどうしたらよいでしょうか?

それとも、テスターのためだけに特別バージョンのExpert Advisorを作成することを提案するのでしょうか?ここでは、ある人が戦闘ロボットを買ってきてテストしているところです。マーケットで、すべてがスピードに最適化されていることをどう説明するか?

 
fxsaber:

このロジックを持つ戦闘ロボット - この時間間隔ではEURUSDのオープンポジションは存在しないはずです。あれば、それを閉じる。

GBPUSDのオープンポジションを持っています。OrderSymbolを毎ティック確認せずに、上記の条件を満たすにはどうしたらよいでしょうか?

それとも、テスターのためだけに特別バージョンのExpert Advisorを作成することを提案するのでしょうか?ここでは、ある人が戦闘ロボットを買ってきてテストしているところです。マーケットには、すべてがテスターのために特別にスピード最適化されていると書くべきでしょうか。

まあ、現在オープンしているポジションの チケットだけをチェックすればよいのですが(つまり、その配列を保持すればよい)。新しいチケットがある場合は、そのチケットで他のすべてのチェックを行う必要があります。なぜ、同じことを何度も確認しなければならないのか?

ちなみに、MQL5にはトレードイベントがあります。そのため、毎回のティックで確認する必要はありません。

 
Alexey Navoykov:

まあ、現在のオープンポジションの ティッカーだけをチェックすれば十分なのですが(それなりに配列も保持します)。

これでは、あまり安くならないでしょう。

ちなみに、MQL5にはトレードイベントもありますよ。そのため、いちいちダニで確認する必要はありません。

クロスプラットフォームのソリューションが書かれることもあります。また、すべてのトレードイベントを取得することを保証するものではありません。

 
fxsaber

それほど安くはないでしょう。

整数演算の差は文字列演算に比べてあまり安くない?まあ、お好きにどうぞ。

 
アレクセイ・ナヴォイコフ

整数演算の差は文字列演算に比べてあまり安くない?まあ、お好きにどうぞ。

必要な理由がわからないけど困惑したそして、チケットを配列したオプションの方が生産性が高いという意見には同意せざるを得ません。

確かに、ある論理の観点から見ると、このような変形は、プログラムの論理的な構成というより、技術的なニュアンスに敷かれていて、非常に人工的なものに見えます。

しかし、私はそれをすべて考慮します。もちろん、コドベースでこの手法に出会ったことはない。

 

MQLで多重継承ができないのは、当然ながら鬱陶しい。しかし、テンプレートとマクロを使えば、どんな方法でも動作させることができます - それらを必要としません )

以下は、私が作ったものです。すべてのソースクラスは、親クラスを定義するテンプレートとして宣言する必要があります。

class CBase { };  // базовый класс

// Макросы, задающие список наследования:

#define  INHERIT1(T)  T<CBase>

#define  INHERIT2(T1, T2)  T2<INHERIT1(T1)>

#define  INHERIT3(T1, T2, T3)  T3<INHERIT2(T1,T2)>

#define  INHERIT4(T1, T2, T3, T4)  T4<INHERIT3(T1,T2,T3)>


// Различные пользовательские классы:

template<typename TParent>
class A : public TParent { public: void a() { Print("A"); } };

template<typename TParent>
class B : public TParent { public: void b() { Print("B"); } };

template<typename TParent>
class C : public TParent { public: void c() { Print("C"); } };


class X : public INHERIT3(A, B, C)  {  };   // Объявляем класс, наследуемый от A, B, C


template<typename T>
void SomeFunc(B<T>& obj)  { obj.b(); }   // Проверочная функция, принимающая класс B


void OnInit()
{
  X x;
  x.a();
  x.b();
  x.c();
  
  SomeFunc(x);
}

もちろん、クラスは並列に継承されるのではなく、順次(設定した順序で)継承されるという点で、微妙な部分もある。特に、過負荷が発生したときの優先順位が違ってきます。また、同じテンプレートクラスが何度も継承の連鎖に参加すると、全く別のクラスになってしまい、お互いに何の関係もなくなってしまいます。だから、ここで気をつけなければならないことがある。しかし、インターフェースでは何の問題もなく、制限なく継承することができます。

 
アレクセイ・ナヴォイコフ

MQLで多重継承ができないのは、当然ながら鬱陶しい。しかし、テンプレートとマクロを使えば、どんな方法でも動作させることができます - それらを必要としません )

以下は、私が作ったものです。すべてのソースクラスは、親クラスを定義するテンプレートとして宣言する必要があります。

もちろん、クラスは同時継承(真の多重継承)ではなく、順次(設定した順序で)継承されるという事実があるため、微妙な部分もある。特に、過負荷が発生したときの優先順位が違ってきます。また、同じテンプレートクラスが何度も継承の連鎖に参加すると、互いに何の関連もない全く別のクラスになってしまいます。だから、ここで気をつけなければならないことがある。しかし、インターフェースに関しては何の問題もなく、制限なく継承することができます。

いい芸当ですね。全体のコツは、パターンを TParentに適用 することにあります。そんなの見たことない。

理由: