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

 
Igor Makanu:

そのようなクラスを作成する場合

ということは、計算で構造体フィールドを多用すると、クラスBの 実行速度が遅くなるのでしょうか?

つまり、オブジェクトの配列をトラバースする時間について議論していたのです)))

この例では、plusでも同じですが、mqlではニュアンスが違っていて、最初に行く暗黙のフィールドが2つあるので、データフィールドはシフトによって接近することになります。

 
Vladimir Simakov:

つまり、オブジェクトの配列をトラバースする時間について議論していたのです)))

この例では、plusでも同じですが、mqlではニュアンスが違っていて、2つの暗黙のフィールドがあり、それが最初に来るので、データフィールドはシフトによって接近する、つまり、参照解除の際に追加の計算が行われます。

ありがとうございます!参考になりました。

 
Vladimir Simakov:

つまり、オブジェクトの配列をトラバースする時間について議論していたのです)))

あなたの例によると、プラスでは同じですが、mqlではニュアンスが違います。最初に行く暗黙のフィールドが2つあるので、データフィールドはオフセットでアクセスされ、すなわち追加の参照解除計算が行われます。

どちらのクラスも似たようなものです。どちらもオフセットによるアクセスですが、構造体の先頭からではなく、クラスの先頭からのアクセスになります。 つまり、構造体そのものは無重力であり、クラスだけがオーバーヘッドを発生させるのです。
 
Vladimir Simakov:

つまり、神秘主義ではなく、物理学の法則が作用しているのです。

物理法則」に当てはまらない。

#include <fxsaber\Benchmark.mqh> // https://c.mql5.com/3/321/Benchmark.mqh

long f1( const int Size, const long Amount = 5 e9 )
{
  long Sum = 0;
  
  for (long i = 0; i < Amount; i++)
  {
    Sum += Size * i;
    
    Sum |= 1;
  }
    
  return(Sum);
}

long f2( const int Size, const long Amount = 5 e9 )
{
  long Sum = 0;
  
  for (long i = 0; i < Amount; i++)
  {
    Sum += Size * (Amount - i);
    
    Sum |= 1;
  }
    
  return(Sum);
}

void OnStart()
{
  Print(_B(f1(2), 1));
  Print(_B(f1(200), 1));
  
  Print(_B(f2(2), 1));
  Print(_B(f2(200), 1));
}


        Alert: Time[Test6.mq5 267: f1(2)] = 3252 ms.
        6553255921290448385
        Alert: Time[Test6.mq5 268: f1(200)] = 4602 ms.
        -8757194524499019775
        Alert: Time[Test6.mq5 270: f2(2)] = 3061 ms.
        6553255931290448385
        Alert: Time[Test6.mq5 271: f2(200)] = 3112 ms.
        -8757193524499019775


これは逆説的な結果である。より複雑な計算も1.5倍高速に実行され、サイズに依存しない。

 
Vladimir Simakov:

そこで、オブジェクト配列のトラバース時間について議論していた)))

あなたの例によると、プラスでは同じになりますが、mqlではニュアンスが異なります。最初に行く暗黙のフィールドが2つあるので、データフィールドはオフセットでアクセスされ、すなわち追加の参照解除計算が行われます。

ウラジミールさんには、アセンブラの勉強をさせていただきました。
そして、アレクセイが言うように、オーバーヘッドはクラスによって生み出されるのです。
このことから、もしクラスがなくても大丈夫なら、手続き型でコードを書いた方が良いという結論に達します。
つまり、スピードを求めないタスクであればクラスで包むことができますが、例えば刻みを扱う場合は、ラッパーを使わずに直接使った方が良いのです。
原則的にはこの方法で、クラスの例を見つけては、そのメソッドを分解していく手続き的なアプローチをとることが多いですね。

 
Roman:

ウラジミールさん、組み立て学習ありがとうございました。
そして、アレクセイが言うように、オーバーヘッドがクラスを作るのです。
このことから、もしクラスがなくても大丈夫なら、手続き型でコードを書いた方が良いという結論に達します。
つまり、スピードを求めないタスクであればクラスで包むことができますが、例えば刻みを扱う場合は、ラッパーを使わずに直接使った方が良いのです。
原則的にはこの方法で、クラスのサンプルを見つけると、そのメソッドを手続き的に分解していくことが多いですね。

掲示板に荒らしが...。
以前は、なぜ無視機能を求めるユーザーがいるのか理解できなかったのですが、ああ、今はどうなんだろう...。

 

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

MQL5におけるOOPに関する質問

fxsaber, 2020.05.30 14:06

どうすればいいのか、まったくわからない。簡単な構造を作ってみました。

        50000000
        50000000
        Alert: Time[Test6.mq5 280: Func(Array1)] = 312 ms.
        1333106752
        Alert: Time[Test6.mq5 281: Func(Array3)] = 1348 ms.
        1333106752
        : sizeof(STRUCT1) = 20
        : sizeof(STRUCT3) = 84

単純な構造体の最初のフィールドへのアクセスが、そのサイズに依存する理由がよくわからないのです。

50Mの要素を配列で使っているんですね。
サイズが20バイトと84バイトの構造体の場合、それぞれ0.93GBと3.91GBのデータ量になります。
そして、あなたの計算の枠内では、おそらくこのメモリはすべてプロセッサのキャッシュを経由しているのでしょう。
そして、この結果を非常に論理的に説明すると、0.93GBのデータは、3.91GBのデータよりも4倍速くメモリからCPUキャッシュにダウンロードされるということになります。

C++のテスト結果はどうでしょうか?
だって、アセンブラコードは見たけど、テスト結果がない、私の見方が悪かったのか?
 
Sergey Dzyublik:

掲示板に荒らしが...。
以前は、なぜ無視機能を求めるユーザーがいるのか理解できなかったのですが、ああ、今はどうなんだろう...。

他人ではなく、自分に気を配るべきだ。
Not you and not for youがその答えだった。
無言で無視する ))

 
Sergey Dzyublik:
50Mの要素を配列で使っているんですね。
20バイトと84バイトの構造体の場合、それぞれ0.93GBと3.91GBのデータ量になります。
そして、その計算の一環として、おそらくこのメモリはすべてプロセッサのキャッシュを経由することになるのでしょう。
そして、この結果を非常に論理的に説明すると、0.93GBのデータは、3.91GBのデータよりも4倍速くメモリからCPUキャッシュにダウンロードされるということになります。

C++のテスト結果はどうでしょうか?
だって、アセンブラコードは見たけど、テスト結果がない、私の見方が悪かったのか?
同じように機能します。少し速くなっただけで、比率は同じですから、ハードウェアですね。
 
Roman:

ウラジミールさん、組み立て学習ありがとうございました。
そして、アレクセイが言うように、オーバーヘッドがクラスを作るのです。
このことから、もしクラスがなくても大丈夫なら、手続き型でコードを書いた方が良いという結論に達します。
つまり、スピードを求めない作業であれば、クラスでラップすれば良いのですが、例えばティックを扱う場合は、ラッパーを使わずに直接書いた方が良いのです。
私は原則的にこの方法をとっており、クラスの例を見つけては、そのメソッドを手続き的に分解していくことが多いです。

クラスの代わりに構造体を使ってもいいんだよ。