定義された要素の配列をクリアする。 - ページ 15

 
Sergey Dzyublik:

演算子については、このようなC++言語では遅すぎるという議論がすでにありました。ArrayCopyで バラバラになる程遅いとは思いませんでした。

演算子内部のインクリメントについては、別の質問です。

 
Stanislav Dray:

なぜ自分を修理して 私を捨てたの?

私は誰も放り出してない。 ものは、返却しました )))

 
Konstantin Nikitin:

誰も追い出さなかった。 ものを返却する ))))

11日にダウンロードしたものを、12日(以下略)に修正し、13日として返却したわけですね。

 
TheXpert:

演算子については、このようなC++言語では遅すぎるという議論がすでにありました。ArrayCopyでバラバラになる程遅いとは思いませんでした。

演算子内部のインクリメントについては、別の質問です。

ここで無駄な操作をする理由もないくらいです。ループ再生中の場合。コピー時に現在のアイテムが範囲外かどうかを確認する必要はない。バウンド内となる。そして、何かを足したり、変数をひとつ増やしたりすることに意味がない。デフォルトでは、i.がある場合。
とにかく、つまらないものばかりです。ご参考までに

 
Stanislav Dray:

11日にダウンロードしたものを、12日(以下略)に修正し、13日として返却したわけですね。

注意を払わなかった。ファイルを差し替えました。

 

この非情なコンペティションでもスケッチされました :-)

template <typename T>
int copyFilter1(const T &src[],T &dst[],T x)
{
        int i=0,j=0,k;
        int total=ArraySize(src);
        ArrayResize(dst,total);
        for(;;) {
                // считаем сколько копировать
                for(k=0;k<total && src[i]!=x;)
                        k++;
                // копируем
                if (k) {        
                        ArrayCopy(dst,src,j,i,k);
                        i+=k;
                        j+=k;
                        total-=k;
                }
                // пропускаем
                for(k=0;k<total && src[i]==x;) 
                        k++;
                if (k) {
                        i+=k;
                        total-=k;
                } else break;
        }
        ArrayResize(dst,j);
        return j;
}

template <typename T>
int copyFilter2(const T &src[],T &dst[],T x)
{
        int i=0,j=0,k;
        int total=ArraySize(src);
        ArrayResize(dst,total);
        for(;i<total;) {
                // копируем всё что не равно x
                for(;i<total && src[i]!=x;i++,j++)
                        dst[j]=src[i];
                // пропускаем всё что равно x
                for(;i<total && src[i]==x;)
                        i++;
        }
        ArrayResize(dst,j);
        return j;
}

今回も未確認です :-) 動作するはずです...

 
Stanislav Dray:

エラーを含むテストを推奨してきた(SemkoとPavlov).

ありがとうございます、修正しました。

マキシム・クズネツォフ

この無慈悲なコンテストで描かれたものでもあります :-)

今回も未確認です :-) 動作するはずです...

が含まれていますが、最初のバリアントがおかしいです

2018.11.15 06:19:01.929 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Pastushak   : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения - 141053 микросекунд
2018.11.15 06:19:01.934 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Korotky     : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   2494 микросекунд
2018.11.15 06:19:01.938 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Fedoseev    : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   1869 микросекунд
2018.11.15 06:19:01.941 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Semko       : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -    785 микросекунд
2018.11.15 06:19:01.945 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Nikitin     : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   2039 микросекунд
2018.11.15 06:19:01.952 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Vladimir    : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   4385 микросекунд
2018.11.15 06:19:01.961 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Peter       : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   7476 микросекунд
2018.11.15 06:19:01.965 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант fann95      : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   1255 микросекунд
2018.11.15 06:19:01.969 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Kuznetsov1  : Контрольная сумма = 7219.502578; элементов - 1000000; время выполнения -   2016 микросекунд
2018.11.15 06:19:01.975 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Kuznetsov2  : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   3965 микросекунд
2018.11.15 06:19:01.975 ArrayDeleteValue__13 (.BrentCrud,M1)    
2018.11.15 06:19:01.975 ArrayDeleteValue__13 (.BrentCrud,M1)    === Порядок в массиве не сохраняется ===
2018.11.15 06:19:01.978 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Kuznetsov3  : Контрольная сумма = 7222.657252; элементов - 998992; время выполнения -    694 микросекунд
ファイル:
 

2つのループのロジックやチェックの回数、和がほぼ100%同じなのに、実行時間が違うというのは、私の誤解に 帰結します。

では、なぜクズネツォフのコードからこのような変種が生まれたのか、改めて考えてみましょう。

    for(;;)
     {
      while(arr[i]!=x && i<j) i++;
      while(arr[j]==x && i<j) j--;
      if(i<j)
        {
         arr[i++]=arr[j--];
        }
      else break;
     }

は、まったく同じことをするものに比べて2倍以上の速さで動作します。

   while(i<j)
     {
      if(arr[i]==x)
         if(arr[j]!=x) arr[i++]=arr[j--];
      else j--;
      else i++;
     }

コンパイラのすばらしさとは?
そんなデザインが本当に可能なのだろうか。

while(arr[i]!=x && i<j) i++;

は、コンパイラがプロセッサのために何か特別なアセンブラの検索コマンドを見つけたのでしょうか?しかし、内部にはi<jのチェックが追加されていますね。

なぜなら、forを通して同じことをすると、実行速度が格段に落ちるからです。

for (;;) if (arr[i]!=x && i<j) i++; else break;

デモスクリプトのコードを添付します。

2018.11.15 13:30:51.354 TestLoop (EURUSD,D1)    вариант while:    Контрольная сумма = 7697.499145747599; элементов - 998975; время выполнения = 771 микросекунд
2018.11.15 13:30:51.357 TestLoop (EURUSD,D1)    вариант for:      Контрольная сумма = 7697.499145747599; элементов - 998975; время выполнения = 1051 микросекунд
2018.11.15 13:30:51.360 TestLoop (EURUSD,D1)    вариант slow:     Контрольная сумма = 7697.499145747599; элементов - 998975; время выполнения = 1531 микросекунд

このようなことがよくあります。不要なゴミに追われているうちに、ちょっと面白いことに気がついた。

開発者の皆さん、実行コードを見て、何がこの違いを生んでいるのか、見ていただけませんか?

今後、より最適なアルゴリズムを作るために、コンパイラの論理を理解する必要があります。

ファイル:
TestLoop.mq5  10 kb
 
ニコライ・セムコ

興味深い観察結果です。また、興味深かったので、次のコードを実行してみました。

void OnStart()
{
     int array[], arr[];
     ArrayResize(arr,1000000);
     for(int i=0; i<1000000;i++)
          arr[i] = rand()%1000;

     int i=0;
     ulong t=GetMicrosecondCount();
     for(; i<1000000; i++)
          int j = arr[i];
     t = GetMicrosecondCount()-t;
     Print("FOR: ", t);
     
     t=GetMicrosecondCount();
     i=0;
     for(;;)
     {
          if( i>=1000000 )
               break;
          int j = arr[i];
          i++;
     }
     t = GetMicrosecondCount()-t;
     Print("FOR-1: ", t);
     
     t=GetMicrosecondCount();
     i=0;
     while(i<1000000)
     {
          int j = arr[i];
          i++;
     }
     t = GetMicrosecondCount()-t;
     Print("WHILE: ", t);
     
     t=GetMicrosecondCount();
     i=0;
     while(true)
     {
          if( i>=1000000 )
               break;
          int j = arr[i];
          i++;
     }
     t = GetMicrosecondCount()-t;
     Print("WHILE-1: ", t);
}


 
Nikolai Semko:

2つのループのロジックやチェックの回数、和がほぼ100%同じなのに、実行時間が違うというのは、私の誤解に 帰結します。

では、なぜクズネツォフのコードからこのような変種が生まれたのか、改めて考えてみましょう。

は、まったく同じことをするのに比べ、2倍以上の速さで動作します。

コンパイラのすばらしさとは?
こんな構成で本当にいいのだろうか。

は、コンパイラがプロセッサのために何か特別なアセンブラの検索コマンドを見つけたのでしょうか?しかし、内部にはi<jのチェックが追加されていますね。

なぜなら、forを通して同じことをすると、実行速度が格段に落ちるからです。

デモ用スクリプトのコードを添付します。

このようなことがよくあります。不要なゴミに追われているうちに、ちょっと面白いことに気がついた。

開発者の皆さん、実行コードを見て、何がこの違いを生んでいるのか、見ていただけませんか?

今後、より最適なアルゴリズムを作るために、コンパイラの論理を理解する必要があります。

フラッグとの相性もいいと思います。
http://osinavi.ru/asm/4.php

そして、不要な演算子・比較のために......。