エラー、バグ、質問 - ページ 2315

 
fxsaber:

なぜ by_ref は by_val よりも遅いのですか?

どこからついてくるのか?

コードが同じ場合

//Test.mqh
        int by_ref(string& var) { return int(var) % 100; }
        int by_val(string  var) { return int(var) % 100; }
//Test.mq5
#include "Test.mqh"
#define  ITERATIONS 1000000
#define  MACRO( X ) \
        { \
                ulong time = GetMicrosecondCount(); \
                for(int i=0; i<ITERATIONS; i++) \
                { \
                        string r = string( rand ); \
                        sum_##X += by_##X(r); \
                } \
                time_##X = GetMicrosecondCount() - time; \
        }
void OnStart()
{
        for ( int i = 0; i < 10; i++ )
                OnStart2( rand());
}
void OnStart2( int rand )
{
        long time_ref, sum_ref = 0;
        long time_val, sum_val = 0;
        MACRO( ref )
        MACRO( val )
        printf( "%+10.3f:%d", (time_ref-time_val)/1000.0, sum_ref-sum_val );
}

も、結果(実行時間差)は同じです。

+12.221:0
+5.099:0
+0.149:0
-13.729:0
+14.531:0
-27.429:0
+26.405:0
-0.839:0
+5.400:0
-4.882:0

いっしゅんいっしょく

 
A100:

それはどこから来るのでしょうか?

#define  ITERATIONS 1000000

void OnStart()
{
   string Str = "1";
   
   for (int i = 0; i < 10; i++)
     Str += Str;
   
   for (int j = 0; j < 5; j++)
   {
     {
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++){
           string r = string(rand()) + Str;
           sum += by_ref(r);
        }
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_ref", time/1000.0, sum);
     }{
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++)
           sum += by_val(string(rand()) + Str);
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_val", time/1000.0, sum);
     }
     
     Print("");
   }
}
//+------------------------------------------------------------------+

int by_ref(string &var){ return int(var) % 100; }
int by_val(string  var){ return int(var) % 100; }


by_ref took 15119.806 milliseconds: sum=-1000000 ll
by_val took 13872.479 milliseconds: sum=-1000000 ll

by_ref took 14433.781 milliseconds: sum=-1000000 ll
by_val took 13817.533 milliseconds: sum=-1000000 ll

by_ref took 13889.424 milliseconds: sum=-1000000 ll
by_val took 14135.603 milliseconds: sum=-1000000 ll

by_ref took 16047.643 milliseconds: sum=-1000000 ll
by_val took 14494.432 milliseconds: sum=-1000000 ll

by_ref took 15542.276 milliseconds: sum=-1000000 ll
by_val took 13843.121 milliseconds: sum=-1000000 ll
 
Nikolai Semko:

KBにグレードをつけたかったのに、うまくいかなかった。また、最近の出版物には全くグレードがないところを見ると、この問題は私だけではないようだ。

ああ、うまくいかないね。

 
fxsaber:
私のrefループとvalループは同じコード(比較はほぼ正しい)ですが、あなたのものは異なっています。
 
A100:
私のループではrefとvalは同じコード(比較はほぼ正しい)ですが、あなたのループでは異なっています。

そう、違うんです。しかし、疑問は残ります。なぜval-variantはrefより顕著に速いのですか?

 
fxsaber:

そう、違うんです。しかし、疑問は残ります。なぜval-variantはrefより顕著に速いのでしょうか?

もしかしたら、refのバリエーションはコンパイラによってあまり最適化されていないのかもしれませんね。

私の考えでは、どちらのバージョンもほぼ同じコード、あるいは完全に同じコードをコンパイルできるはずですが、コンパイラは異なる処理をしています。

 
TheXpert:

もしかしたら、refの方がコンパイラによって最適化されていないのかもしれません。

両者はほぼ同じコード、あるいはまったく同じコードをコンパイルできるはずなのに、コンパイラは違うことを考えているようだ

実はこの質問は開発者向けのもので、乖離の理由に根拠があるのです。

普段はスピードを重視して、すべてリファレンスで渡すようにしています。そして、これはいくつかのビルドで正当化されました。でも、今となってはそう思えます。

 
Alexey Kozitsyn:

+1.何かが壊れているようだ。ビルド1881 x64。Win10です。起動時にCPUに20%以上(i5 8600k)、RAMに650-700mb(増加なし)の負荷がかかります。

タスクマネージャに「応答なし」のステータスが表示される。

そして、もう一つの端末1881(Openingではない)は問題なく動作しています。

追加されました。

結局、起動はした。しかし、起動に非常に時間がかかり、これは通常ではありえないことです。そして、ターミナルを閉じて、もう一度開いてみた。即座に開封。どうやらデータの読み込みに問題があったようです。

端末の再インストールで解決。誤って全ての設定やグラフが入ったフォルダを持ち出してしまったので)もう一度全て描き直しましたが、今は正常に動作しています。
削除済み  
reztor:
解決策は、端末を再インストールすることでした。また、誤ってすべての設定とグラフの入ったフォルダを削除してしまいました)もう一度すべてを描き直しましたが、今は正常に動作しています。

これは必要ないことでした。単純にnews.datファイルを削除 すればいいのです。

 
TheXpert:

もしかしたら、refの変形はコンパイラによってより悪く最適化されているかもしれません。

私の考えでは、どちらのオプションもほぼ同じコード、あるいは完全に同じコードをコンパイルするはずですが、コンパイラは異なる方法でカウントしています。

最終的なコードとその実行時間の関係は?

たとえば、次のように変更します というように、ループが絶対同一になるように

#define  ITERATIONS 1000000
void OnStart()
{
   string Str = "1";
   for (int i = 0; i < 10; i++)
     Str += Str;
   for (int j = 0; j < 5; j++)
   {
     {
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++)
           sum += by_ref(string(rand()) + Str);
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_ref", time/1000.0, sum);
     }
     {
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++)
           sum += by_val(string(rand()) + Str);
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_val", time/1000.0, sum);
     }    
     Print("");
   }
}
int by_ref(string var){ return int(var) % 100; }
int by_val(string var){ return int(var) % 100; }

その結果..:

by_refにかかった時間:18354.547ミリ秒:sum=1865600ll
by_valは18318.319ミリ秒を要した:sum=1861628ll

by_refにかかった時間:18416.747ミリ秒 sum=1904488ll
by_val took 18221.978 milliseconds: sum=1907860ll

by_refにかかった時間:18301.009ミリ秒 sum=1757988ll
by_valは18545.258ミリ秒を要した:sum=1949720ll

by_refにかかった時間:18373.648 ミリ秒:sum=1867160ll
by_valは17972.432 ミリ秒を要した:sum=1760308ll

by_refにかかった時間:19426.076 ミリ秒:sum=1795564ll
by_valは19177.485 ミリ秒を要した:sum=1826360ll

はほぼ同じ...それとも、コンパイラが同じループの中で違うコードを作ってしまったとお考えですか?

思い出してください-こんなものがあった のです。

by_refに13889.424 ミリ秒かかった:sum=-1000000ll
by_valは14135.603 ミリ秒かかった:sum=-1000000ll

と別のコードに...と、時間的には同じくらいの差がありますが、コードや関数そのものは全く同じです