MQL5におけるOOPに関する質問 - ページ 87

 
Vladimir Simakov:
質問です。なぜアコーディオンが必要なのか?1つのメソッド、1つのクラスで、球状の馬で、そう、物理的な真空で(まあ、息切れするけど)))、なら、はい、意味がありますね。そして、実際のプロジェクトでは、グローバルレベルでのクラス、またはハンドラの先頭にこのすべてのtrichomudin(余分なバーボンのために申し訳ありません)))を処理するlonerのいずれか、および、任意の場所でそこから直接要求)))))。

それは、タスクを分配し、下位のクラスの小さな群れから結果を得るクラスマネージャーです ))))

総体的に、冷静に説明することが難しい

しかし、問題は、異なるメソッドから共通フィールドの値を読み取る際に、共通フィールドのアドレス指定がどのように行われるか、そして、非常に頻繁に行われるかです。

 
Igor Makanu:

それは、タスクを分配し、下位のクラスの小さな群れから結果を得るクラスマネージャーです ))))

総体的に、冷静に説明することが難しい

しかし、問題は、異なるメソッドから共通フィールドの値を読み取る際に、共通フィールドのアドレス指定がどのように行われるか、そして、非常に頻繁に行われるかです。

見てください。ハンドラの冒頭で、gSomeGlobal.SomeEvent(...)、シングルならAlone::SomeEvent(...)を起動し、このメソッドで必要な状態処理を行い、ゲッターを介して必要なデータを要求するだけです。高頻度スキャルパーでない限り、ここでは特別なオーバーヘッドはありませんが、すべての速度擁護派をねじ込むことができます)))。
 
Vladimir Simakov:
こちらもご覧ください。ハンドラの冒頭で、gSomeGlobal.SomeEvent(...)、シングルならAlone::SomeEvent(...)を起動し、このメソッドで必要な状態処理を行い、ゲッターを介して必要なデータを要求するだけです。高頻度スキャルパーでない限り、ここでは特別なオーバーヘッドはありませんが、すべての速度擁護派をねじ込むことができます)))。

mt5の性能は毎秒10500オーダーで十分なので、チャンネルは十分だったでしょう。

真偽を確かめたかったんだ!やりたいことがあるなら自分でやれよ! )))

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"

#define  TST_COUNT 1 e10

#define    SpeedTest(count,msg,EX)   {uint mss=GetTickCount(); ulong lim = count; for(ulong cnt=0;cnt<lim&&!_StopFlag;cnt++){EX;} \
                                    printf("%s: loops = %llu ms=%u",msg,lim,GetTickCount()-mss);}
//+------------------------------------------------------------------+
class A
{
private:
   double            _Ask, _Bid;
   double            f1()  { return(_Ask + 1.0/(1.0+(double)rand())); }
   double            f2()  { return(_Bid + 1.0/(1.0+(double)rand())); }
   double            f3()  { return(_Ask/_Bid + 1.0/(1.0+(double)rand())); }
public:
   double            calc(const MqlTick &tick){ _Ask = tick.ask; _Bid = tick.bid; return(f1() + f2() + f3()); }
};
//+------------------------------------------------------------------+
class B
{
private:
   double            f1(const MqlTick &t)  { return(t.ask + 1.0/(1.0+(double)rand())); }
   double            f2(const MqlTick &t)  { return(t.bid + 1.0/(1.0+(double)rand())); }
   double            f3(const MqlTick &t)  { return(t.ask/t.bid + 1.0/(1.0+(double)rand())); }
public:
   double            calc(const MqlTick &tick){ return(f1(tick) + f2(tick) + f3(tick)); }
};
//+------------------------------------------------------------------+
void OnStart()
{
   A a;
   B b;
   MqlTick rnd_tick;
   for(int i=0; i<5; i++)
   {
      SpeedTest(TST_COUNT, "class A : ",
               rnd_tick.ask = 1.0 + 1.0 / (1.0 + (double)rand());
               rnd_tick.bid = 1.0 + 1.0 / (1.0 + (double)rand());
               double res = a.calc(rnd_tick);
      );
   
      SpeedTest(TST_COUNT, "class B : ",
               rnd_tick.ask = 1.0 + 1.0 / (1.0 + (double)rand());
               rnd_tick.bid = 1.0 + 1.0 / (1.0 + (double)rand());
               double res = b.calc(rnd_tick);
      );
   }
}
//+------------------------------------------------------------------+

2020.07.25 18:00:07.293 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.25 18:00:45.273 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=37968

2020.07.25 18:01:31.405 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.25 18:02:09.423 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38016

2020.07.25 18:02:55.558 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46125

2020.07.25 18:03:33.635 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38078

2020.07.25 18:04:21.969 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=48344

2020.07.25 18:05:00.113 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38140

2020.07.25 18:05:46.503 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46391

2020.07.25 18:06:24.573 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38062

最適化には速度が重要なので、それを知りたかったのです。

一般に、リファレンスはすべてのメソッドに現在の価格を 渡す必要があります。



UPDです。

//+------------------------------------------------------------------+
class C
{
private:
   double            f1(const double &a, const double &b)  { return(a + 1.0/(1.0+(double)rand())); }
   double            f2(const double &a, const double &b)  { return(b + 1.0/(1.0+(double)rand())); }
   double            f3(const double &a, const double &b)  { return(a/b + 1.0/(1.0+(double)rand())); }
public:
   double            calc(const MqlTick &tick){const double ask = tick.ask; const double bid = tick.bid; return(f1(ask,bid) + f2(ask,bid) + f3(ask,bid)); }
};
//+------------------------------------------------------------------+

2020.07.25 19:03:37.210 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.25 19:04:15.201 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.25 19:04:53.188 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=37984

2020.07.25 19:05:39.321 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46125

2020.07.25 19:06:17.313 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.25 19:06:55.306 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=37985

 
Igor Makanu:

mt5の性能は毎秒10500オーダーで十分なので、チャンネルは十分だったでしょう。

真偽を確かめたかったんだ!やりたいことがあるなら自分でやれよ! )))

2020.07.25 18:00:07.293 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.25 18:00:45.273 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=37968

2020.07.25 18:01:31.405 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.25 18:02:09.423 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38016

2020.07.25 18:02:55.558 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46125

2020.07.25 18:03:33.635 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38078

2020.07.25 18:04:21.969 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=48344

2020.07.25 18:05:00.113 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38140

2020.07.25 18:05:46.503 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46391

2020.07.25 18:06:24.573 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38062

最適化には速度が重要なので、それを知りたかったのです。

一般に、リファレンスはすべてのメソッドに現在の価格を 渡す必要があります。



UPDです。

2020.07.25 19:03:37.210 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.25 19:04:15.201 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.25 19:04:53.188 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=37984

2020.07.25 19:05:39.321 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46125

2020.07.25 19:06:17.313 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.25 19:06:55.306 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=37985

手始めに同じ労働条件にする)))))なぜなら、絶対に不要な代入演算子(2個)を挿入してしまったため、故意に最適でないコードを作ってしまったからです)))

//+------------------------------------------------------------------+
class A
{
private:
   double            _Ask, _Bid;
   double            f1()  { return(_Ask + 1.0/(1.0+(double)rand())); }
   double            f2()  { return(_Bid + 1.0/(1.0+(double)rand())); }
   double            f3()  { return(_Ask/_Bid + 1.0/(1.0+(double)rand())); }
public:
   void              Init() {_Ask = 1.0 + 1.0 / (1.0 + (double)rand());
                             _Bid = 1.0 + 1.0 / (1.0 + (double)rand());}
   double            calc(){return(f1() + f2() + f3()); }
};
//+------------------------------------------------------------------+
class B
{
private:
   double            f1(const MqlTick &t)  { return(t.ask + 1.0/(1.0+(double)rand())); }
   double            f2(const MqlTick &t)  { return(t.bid + 1.0/(1.0+(double)rand())); }
   double            f3(const MqlTick &t)  { return(t.ask/t.bid + 1.0/(1.0+(double)rand())); }
public:
   double            calc(const MqlTick &tick){ return(f1(tick) + f2(tick) + f3(tick)); }
};
//+------------------------------------------------------------------+
void OnStart()
{
   A a;
   B b;
   MqlTick rnd_tick;
   for(int i=0; i<5; i++)
   {
      SpeedTest(TST_COUNT, "class A : ",
               a.Init();
               double res = a.calc();
      );
   
      SpeedTest(TST_COUNT, "class B : ",
               rnd_tick.ask = 1.0 + 1.0 / (1.0 + (double)rand());
               rnd_tick.bid = 1.0 + 1.0 / (1.0 + (double)rand());
               double res = b.calc(rnd_tick);
      );
   }
}

そして、今度は質問です。あなたにとって、どちらが便利ですか?もちろん、メソッドのパラメーターを介してリンクの連鎖をドラッグすることもできますし、うまくやることもできます。自分で速度を比較する)))

 
Vladimir Simakov:

しかし、あなたは絶対に不要な代入演算子(2個)を取ってしまい、その結果、承知の上で最適ではないコードを作ってしまった)))

私じゃない!

IBM Knowledge Centerです!https://www.ibm.com/support/knowledgecenter/ru/ssw_aix_72/performance/coding_style_best_perf.html



条件は同じで、tickごとにクラスマネージャ(またはスーパークラス、私は知らない)を呼び出す必要があります。

そして、その戦略に従って動作する残りのクラスを呼び出します。

しかし、議論するために、バリアントCは本当にスピードで勝っているので、knoelege_centerが真実を語っているようなものです。

 
Pavel Verveyko:

これは不具合なのか、機能なのか疑問ですが)

クラスインスタンスの中に構造体があります。

構造体の中身が見えるようにドットを入れました。
しかし、角括弧をつけた場合のみ表示される。
構造は1つのインスタンスになっていますが、

、クラスが配列要素 でなければ問題は解決します。




ここに "つっこみ "のコードがあります。

は、エラーがあってもコンパイルしてみる。エディタを「目覚めさせる」こともある

 
Igor Makanu:

飛んでもない

IBM Knowledge Centerです!現在の価格を 渡す必要があります。



UPDです。

2020.07.25 19:03:37.210 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.25 19:04:15.201 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.25 19:04:53.188 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=37984

2020.07.25 19:05:39.321 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46125

2020.07.25 19:06:17.313 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.25 19:06:55.306 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=37985

イゴール・マカヌ

これは私ではありません

this is IBM Knowledge Center !https://www.ibm.com/support/knowledgecenter/ru/ssw_aix_72/performance/coding_style_best_perf.html



そこで条件は同じで、ティックごとにクラスマネージャー(またはスーパークラス、私は知らない)を呼び出す必要があります。

そして、その戦略に従って動作する残りのクラスを呼び出します。

しかし、ポイントとして、オプションCはスピードで本当に勝っている、つまり、knoelege_center kindaは真実を語っています。

もちろん勝ってる)しかし、最適に書かれているからではなく、コンパイラが賢くなったからです)。純粋な最適化リリースコードでは、Ask値とBid値の割り当てはありません)))しかし、処理するパラメータがもう少し少なくなり、プロジェクトのビジネスロジックがインジケータによる注文を開く程度になると、プロジェクト全体でリンクの文字列をドラッグするのに疲れるのが目に見えています))))そうそう、過剰な最適化の罪については、すでにお話しましたね。信じてください、98%のケースで必要ないのです。

 
Vladimir Simakov:

そうそう、最適化しすぎることの罪については、すでにお話しましたね。信じてください、98%は必要ないのです。

そうです!...でも、直感で、ちゃんとしないとダメなんだと思う )))

なるほど、ありがとうございます。この研究には良いセンスがありますね。

 
Igor Makanu:


UPDです。

2020.07.25 19:03:37.210 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46141

2020.07.25 19:04:15.201 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.25 19:04:53.188 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=37984

2020.07.25 19:05:39.321 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46125

2020.07.25 19:06:17.313 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.25 19:06:55.306 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=37985

このような方法も試してみてください。

class D
{
   double f1(const double &a, const double &b)  { return(a + 1.0/(1.0+(double)rand())); }
   double f2(const double &a, const double &b)  { return(b + 1.0/(1.0+(double)rand())); }
   double f3(const double &a, const double &b)  { return(a/b + 1.0/(1.0+(double)rand())); }
   
public:
   double calc( const MqlTick& tick )
   {
      return f1( tick.ask, tick.bid ) + f2( tick.ask, tick.bid ) + f3( tick.ask, tick.bid );
   }
};
 
Koldun Zloy:

また、このような方法も試してみてください。

2020.07.26 09:39:21.350 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46157

2020.07.26 09:39:59.402 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38046

2020.07.26 09:40:37.455 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=38063

2020.07.26 09:41:15.485 class_global (EURUSD,H1) class D : : loops = 10000000000 ms=38031

2020.07.26 09:42:01.749 class_global (EURUSD,H1) class A : : loops = 10000000000 ms=46266

2020.07.26 09:42:39.754 class_global (EURUSD,H1) class B : : loops = 10000000000 ms=38000

2020.07.26 09:43:17.753 class_global (EURUSD,H1) class C :: ループ数 = 10000000000 ms=38000

2020.07.26 09:43:55.743 class_global (EURUSD,H1) class D : : loops = 10000000000 ms=37984

同じ値、テスト速度はなぜか「浮遊」しているが、リンクでメソッドにパラメータを渡す 方がまだ効率的である