defineの専門家に質問 - ページ 4

 
Alexandr Andreev:

正常な機能の展開は自明である

i.e 例えば for (int i=0; i<ArraiSize(max); i++)

ここでArraiSize(max); が展開され、与えられた配列のサイズに対するアドレスのようなものが得られます(配列を見ると、それはそのサイズを変数に持ち、ここではこの変数「メモリ上のアドレス」に代入しています)、つまり変数に変更する意味は 全くありません。

for (int i=0; i<ArraiSize(max); i++)

и

for (int i=0; i<size; i++)

この場合、ArraiSize(max)とsizeは同じタイミングで配列の大きさを決定 します

誤記

tested: 1000回試しました。3つの配列と各配列の3つのネストされたループ、2つのバリエーション:1番目と 2番目

の結果は安定しています(3回テスト)。

2020.11.02 21:17:25.952 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=114.5013

2020.11.02 21:17:40.713 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=99.7722

テスト方法について議論する意味がわからない - 非常に長く、必要なこと
 
Roman:

この例のループでは、タイミングについて納得がいかないと思います。
逆に、結果をサイズ変数に取り込んで、条件の中で使用することをお勧めします。
ArraiSize(max) 各反復でのループが不必要に巻き戻され、ループの実行速度が遅くなるため。

ArraiSize(max) 関数は、配列から長さのレコードを展開し、そのセルを返す。

そして、どのような変数であっても、この場合はサイズ - 配列の長 さが格納されているセルの アドレスです。

つまり、出力では同じものが得られ、ループの過程で配列のサイズを 変えても、1つ目の場合も2つ目の場合も、セルあたりのアドレスは変わりません。

masの値は常に静的(参照ではない)なので、単純に他のロジックは存在し得ない)))

ArraiSize(max) 関数自体は、max 配列のメモリセクションを配列の長 さに使用することを述べて います;これはコンパイル段階で実行されます - 関数展開

 
Igor Makanu:

誤記

テスト:1000回計測、3つの配列と各配列に3つのネストしたブルートフォースループ、2つのバリエーション:1番目と 2番目

の結果は安定しています(3回テスト)。

2020.11.02 21:17:25.952 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=114.5013

2020.11.02 21:17:40.713 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=99.7722

テスト方法について議論する意味がわからない - 非常に長く、必要なこと

その後、ビルドにいくつかの問題が発生しました...。

 
Alexandr Andreev:

となると、組み立てに問題があるのでは......。

出力が同じであることは明らかです。
しかし、このメモリ部はアクセスが異なる、そこがポイントでした。
変数へのアクセスは、変数にすでに値が含まれているため、関数へのアクセスよりも高速になります。
そして、関数はこの値を取り出して返す、つまりメモリセルを参照する必要があるのですが、これは不要な命令です。

イゴールの例は、私が言っていたことの確認に過ぎません。

 
Alexandr Andreev:

その後、組み立てに問題が発生し......。

うそ臭い

ArraySize()は反復毎に呼び出されます。

配列のサイズを毎回チェックしなくても、プロシージャの呼び出しと、少なくとも配列のサイズを格納する変数のチェックは行われます。

これは私が書いているテストです。ループの中で配列のサイズを変更 しますが、ループはそのまま中断されます。つまり、ループの各反復で、配列のサイズはループ本体が実行された後に決定されます。

void OnStart()
{
   int arr[];
   int sz = ArrayResize(arr, 100000);
   int cnt = 0;
   for(int i = 0; i < ArraySize(arr); i++)
   {
      ArrayResize(arr, sz--);
      cnt++;
   }
   printf("cnt = %i", cnt);   //cnt = 50001
}
 
Igor Makanu:

うそ臭い

ArraySize()は反復毎に呼び出されます。

配列のサイズを毎回チェックしなくても、プロシージャが呼び出され、少なくとも配列のサイズを格納する変数がチェックされます。

私が書いているテストは以下の通りです。ループ内で配列のサイズを変更し、ループは期待通りに終了します。つまり、各ループ反復において、ループ本体が実行された後に配列のサイズが定義されるのです。

テストの完全なコードを教えてください。

ローマ字 表記

出力で同じものが得られるのは明らかです。
しかし、このメモリ断片は異なる形でフェッチされる、そういうことです。

イゴールの例は、私が言っていたことの確認に過ぎません。

そして、あなた自身がテストを行った結果、私は110000000000000のところにいるのですが、そんなことは起こりません。

より正確には、どのテストでも、LONG_MAXの 繰り返しでも全く発生しません
 
Alexandr Andreev:

ArraiSize(max) 関数を拡張し、配列から長さを記録したセルを取り出し、配列の長 さを記録したセルのアドレスを返す。

そして、どのような変数であっても、この場合はサイズ - 配列の長 さが格納されているセルの アドレスです。

つまり、出力では同じものが得られ、ループの過程で配列のサイズを変えても、1つ目の場合も2つ目の場合も、セルあたりのアドレスは変わりません。

masの値は常に静的(参照ではない)なので、単純に他のロジックは存在し得ない)))

ArraiSize(max) 関数自体は、配列の長さに対応する max 配列のメモリ領域を使用するように指示しており、これはコンパイル段階で実行されます - 関数展開

この意見は時期尚早と思われます。ArraiSize関数の裏側で一体何が起こっているのかは不明ですよね。MQLではブラックボックスになっています。for (int i=0; i<ArraiSize(max); i++)で複数の命令が実行される可能性は十分にあります。例えば、ある関数が入力パラメータをチェック することがあります。保存 - データをスタックから押し出します。レジスターを保存します。レジスタを復元する。Function call - 呼んでから、返す。つまり、見えないところでいろいろなことが起きているかもしれない、ということです。だから、コンパイラに頼らず、for (int i=0; i<size; i++) を使った方が良いのです。

 
Alexandr Andreev:

自分でテストしたのか、110000000000000で持っていない


昔、テストされたから、ループの中でしか変数を使わないんだ。

 
Roman:

これはずいぶん前にテストしたことなので、変数はループの中でしか使いません。

コードを使ったテストを見せてください

 
Alexandr Andreev:

コードテストを見せてください

What test? ))
あなた自身は、ループ条件の両方のバリエーションを示しました。
Igorは上のコードもあげています。
ループの実行をsize変数とループ条件のArraySize() で計測するだけです。