ループの後ろで変数を宣言するのか、ループの中で宣言するのか? - ページ 5

 
pivalexander:

私は、関数の最初にたくさんの変数を作成するよりも、コードを論理的なブロックに分割し、その中で必要な変数を宣言することを好みますが、そのほとんどは、どこか遠くのブロックでしか必要ではありません

一箇所だけに必要な変数については、特にブロックが小さい場合は、ブロック自体の前に宣言することが理にかなっています。しかし、ブロックが十分に大きく、変数が他の場所で必要な場合、私は関数の最初に宣言することを好みます。ここでは常識的な判断が必要ですが。

 
pivalexander:

ループ本体が空の状態で実行された場合の結果は大きく異なり、より高速になります

Test1, время выполнения: 0.548275 сек.
Test2, Время выполнения: 0.313978 сек.

マイクロ秒で何を測っているのか ... 続きを読む本当に現実的なテストをしているのか?

;)

こんなテストもあります。

#define  N 8

#define    test(M,S,EX,res) {                             \
uint mss=GetTickCount();                                 \
ulong nn=(ulong)pow(10,M);                               \
for(ulong tst=0;tst<nn && !_StopFlag;tst++) \
{ EX;  res }                                             \
printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   string result;
   string s1;  test(N,"1. s1=",s1=(string)tst, result = s1;);
   string s2;  test(N,"2. s2=",s2=(string)tst, result = s2;);
   string s3;  test(N,"3. s3=",s3=(string)tst, result = s3;);
   string s4;  test(N,"4. s4=",s4=(string)tst, result = s4;);
   string s5;  test(N,"5. s5=",s5=(string)tst, result = s5;);

   test(N,"1. q=",string q=(string)tst, result = q;);
   test(N,"2. w=",string w=(string)tst, result = w;);
   test(N,"3. e=",string e=(string)tst, result = e;);
   test(N,"4. r=",string r=(string)tst, result = r;);
   test(N,"5. t=",string t=(string)tst, result = t;);
  }

2019.08.18 12:14:20.765 SpeedTest (EURUSD,H1) 1. s1=: loops=100000000 ms=8156

2019.08.18 12:14:29.127 SpeedTest (EURUSD,H1) 2. s2=: loops=100000000 ms=8359

2019.08.18 12:14:37.353 SpeedTest (EURUSD,H1) 3. s3=: loops=100000000 ms=8235

2019.08.18 12:14:45.464 SpeedTest (EURUSD,H1) 4. s4=: loops=100000000 ms=8109

2019.08.18 12:14:53.557 SpeedTest (EURUSD,H1) 5. s5=: loops=100000000 ms=8094

2019.08.18 12:15:01.446 SpeedTest (EURUSD,H1) 1. q=: loops=100000000 ms=7890

2019.08.18 12:15:09.159 SpeedTest (EURUSD,H1) 2. w=: loops=100000000 ms=7703

2019.08.18 12:15:16.903 SpeedTest (EURUSD,H1) 3. e=: loops=100000000 ms=7750

2019.08.18 12:15:24.716 SpeedTest (EURUSD,H1) 4. r=: loops=100000000 ms=7813

2019.08.18 12:15:32.661 SpeedTest (EURUSD,H1) 5. t=: loops=100000000 ms=7937

 
Igor Makanu:

マイクロ秒で何を測っているのか ... 続きを読むそのテストは本当に現実に即しているのですか?

   ulong  time_finish = GetMicrosecondCount();
   ulong  res = time_finish - time_start;

それが私の測定方法です。

 
pivalexander:

こうやって測っているんです。

それはわかるが、少なくとも数秒は計測する必要がある

Windowsはリアルタイムではありませんね。 また、バックグラウンドタスクもWindowsのリソースを必要としますので、あなたのテストはシステムタイマーと バックグラウンドプロセスの精度が低いというレベルです

少なくとも5秒のテストは、少なくとも信頼できる情報である。

 
Igor Makanu:

それはわかるのですが、少なくとも数秒は計測する必要があります

Windowsはリアルタイムシステムではない、バックグラウンドタスクもWindowsのリソースを必要とするため、システムタイマーとバックグラウンドプロセスの精度が低いことがテストの前提となっている。

少なくとも5秒のテストは、少なくとも信頼できる情報である。

数秒ずつ測定した結果、同じでした。

 

一般的には、テストとはいえ100%正しいものを作ろうと思い、何も手抜きをしないようにしました。

void OnStart()
{
  int count= (int)10 e6;

  { 
    uint t= GetTickCount();
    int sum=0;
        
    for (int i=0; i<count; i++)
    {
       string st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test1, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
  
  {
    uint t = GetTickCount();
    int sum=0;
    string st = "";
    for (int i=0; i<count; i++)
    {
       st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test2, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
}

最適化されていないモードでは、2番目のバリエーションが実際に速く、最適化されたモードではその逆となることが判明しました。一方、2つ目のバリエーションは、なぜか最適化前より遅くなる)

 
pivalexander:

一度に数秒ずつ測定しても結果は同じで、なぜここに結果を掲載するのに時間がかかるのか

と数回同じテストを実行する必要があります、取得する次のテストでのキャッシュ操作の高い確率があるため、それは小さな違いで2同一のテストが異なって実行されることが出てくるかもしれない - あなたは、同じテストの違いが表示されないのでしょうか?

それはあなた次第です。上に書いたように、私は誰も信用しません、Windowsやプロセッサや自分自身さえも;)。


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

一般的に、私はテストが、100%正しい、何も切り取られていないことを作ることにしました。

最適化されていないモードでは、2番目のバリエーションが確かに速いのですが、最適化されたモードではその逆です。そして、2つ目の方法は、なぜか最適化前より遅くなる)

srand()がないのは事実ですが、rand()はコンパイラによって非常にクールに最適化されていると言いました ;)

そして、スクリプトのテキストを少なくとも2回コピーしてください - そうすれば、コンパイラが何を切り取ったのかがわかります ;)

 
pivalexander:

メモリとプロセッサがどう関係するんだ? 最適化の話だろ、本末転倒な理論家だな)

あなたの推論の括弧よりさらに進んで、コンパイラがどのように働き、その最適化がどのように働くかを理解すれば、どんなコンパイラの目的も、コードの実行クロックサイクルの数を減らし、非連続のメモリアクセスをできるだけ減らすことであることがわかるでしょう。 それに対応して、どんなコンパイラの最適化の結果も、それが存在すれば、どんな馬鹿なテストをしなくても、あらかじめあなたにわかることでしょう。テストを使って2+2=4と考えるようなもの...。

そして、本の理論家について...。この理論家は87年から執筆活動を始め、EC1020やZX Spectrumに始まり、複数のコンパイラを書き、自分の会社に600人以上のプログラマーを雇った...。

 
Aleksandr Matveev:

推論の括弧よりさらに進んで、コンパイラの仕組みと最適化の仕組みを理解すれば、どんなコンパイラでも、コードの実行クロックサイクルの数を減らし、非連続的なメモリアクセスをできるだけ減らすことが目的であり、その結果、どんなコンパイラの最適化があっても、その結果は、馬鹿なテストをしなくてもあらかじめ分かっていることが分かるはずです。テストを使って2+2=4と考えるようなもの...。

そして、本の理論家について...。この理論家は、87年からEU1020やZX Spectrumに取り組み、自作のコンパイラをいくつも書き、600人以上のプログラマーを会社に招き入れた...という経歴の持ち主。

本で自画自賛して忙しいくせに、本質的なことは何も書いてなくて、ただ理論に踊らされているだけ...これを読めば理解できるだろう...。メモリとCPU、CPUとメモリ、電源についてはもっと、そこでも使われているのですが・・・。

 
文字列は小さな内部バッファを持つことができ、小さな文字列の場合、データは丸ごとそこに行くことができることをご存知ですか?つまり、ほとんどの些細なケースを高速化することです。malloc()のキャッチをいじっていたら、文字列が15文字程度より短い場合、mallocは全くいじらないことに気がつきました。あなたのテストはどうですか?
理由: