mql5言語の特徴、微妙なニュアンスとテクニック - ページ 130 1...123124125126127128129130131132133134135136137...247 新しいコメント fxsaber 2019.03.15 10:15 #1291 // ArrayResize с освобождением памяти template <typename T> int ArrayResize2( T &Array[], const int NewSize, const int Reserve = 0 ) { T ArrayTmp[]; ArraySwap(Array, ArrayTmp); const int Res = ArrayResize(Array, NewSize, Reserve); if (Res > 0) ArrayCopy(Array, ArrayTmp, 0, 0, MathMin(Res, ArraySize(ArrayTmp))); return(Res); } pivomoe 2019.03.15 11:13 #1292 fxsaber: ありがとうございます。ArraySwap関数を使うことは、私には思いつかなかったでしょう。 この関数は、サイズの増加と減少の両方、つまりArrayResizeの完全なアナログとして動作すると理解しています。 ArraySwap、ArrayResize、ArrayCopyの 3つの関数を呼び出すのではなく、配列が拡大されたときに標準のArrayResize関数を呼び出すだけでよいのではないでしょうか? p.sMqlTickの 配列を1,000,000から500,0000に減らすときに、あなたのバージョンと私のバージョンを2つコピーしてテストしました。あなたのバージョンでは22ミリ秒です。私のは37-38でやってます。 fxsaber 2019.03.15 11:29 #1293 pivomoe:ArraySwap、ArrayResize、ArrayCopyの 3つの関数を呼び出すよりも、配列が大きくなったときに標準のArrayResizeを単純に呼び出す方が良いのではありませんか?考えたけどやらなかったのは、実はもっと微妙なところがあるからです。だから、饒舌なバージョンにこだわることにしたんです。 その機微のひとつが、これです。コンストラクタ/デストラクタを持つ構造体の配列を取ると、ArrayResizeは値の差に等しい量だけ、どちらかの方向に呼び出します。 しかし、ArrayCopyを適用 すると、すべてのコンストラクタが呼び出されます。ArrayTmpの削除は、すべてのデストラクタの呼び出しになります。つまり、ArrayResize2 は本当の ArrayResize ではないのです。 pivomoe 2019.03.15 13:42 #1294 このようにArrayResize( arr, new_size, -1)と書けばよいことがわかりました。しかし、あなたのバージョンの方がまだ速く、約22ミリ秒対37ミリ秒です。 fxsaber 2019.03.17 18:00 #1295 EAのフレームモードから外れてしまい、再度フレームモードに戻す必要がある場合があります。次のExpert Advisorは、この方法を示しています。// Создание mqd-Файла из Тестера, чтение mqd-файла из Терминала во фрейм/стандартном режиме работы советника. input int Range = 0; // 0..10 void OnTesterInit( void ) {} void OnTesterDeinit( void ) {} #define TOSTRING(A) #A + " = " + (string)(A) + " " void OnTesterPass( void ) { ulong Pass; string Name; long ID; double Value; while (FrameNext(Pass, Name, ID, Value)) // Прочли очередной проход из mqd-файла. Print(TOSTRING(Pass) + TOSTRING(Name) + TOSTRING(Value)); // Вывели данные mqd-файла } double OnTester( void ) { if (MQLInfoInteger(MQL_OPTIMIZATION)) { uchar Data[]; FrameAdd(TerminalInfoString(TERMINAL_DATA_PATH), 0, MathRand(), Data); // Отправили данные в mqd-файл Терминала. } return(0); } void OnInit() { if (MQLInfoInteger(MQL_TESTER)) { // OnInit для Тестера } else if (FrameFirst()) // Удалось инициализировать mqd-файл. { OnTesterInit(); OnTesterPass(); } } void OnDeinit( const int ) { if (MQLInfoInteger(MQL_TESTER)) { // OnDeinit для Тестера } else OnTesterDeinit(); } void OnTick() { static const bool IsTester = MQLInfoInteger(MQL_TESTER); if (!IsTester) return; // OnTick для Тестера. } 最適化後、以下のようになります。 Pass = 0 Value = 25534.0 Pass = 1 Value = 12915.0 Pass = 7 Value = 25534.0 Pass = 8 Value = 12915.0 Pass = 6 Value = 6528.0 Pass = 5 Value = 2523.0 Pass = 3 Value = 22229.0 Pass = 2 Value = 9767.0 Pass = 4 Value = 7748.0 Pass = 9 Value = 25534.0 Pass = 10 Value = 12915.0 フレームモードのExpert Advisorをオフにして、標準モードで実行すると、最適化中に取得したのと同じデータが表示されます。 この方法なら、何度でもOptimizationの 結果に戻ることができます。 SZY フレームモードのターミナルで開いたチャートでは、Expert Advisorを実行することはできないんだ。そのため、標準モードで実行する場合は、フレームを開いていないチャートで実行する必要があります。 fxsaber 2019.03.21 07:14 #1296 extern はハードコードされたマクロになりました#undef extern #define extern // macro redefinition 従って、MT5のmq4コードを変更せずに動作させることは、必ずしも可能ではありません。 Alexey Viktorov 2019.03.21 07:22 #1297 fxsaber: extern теперь является жестко заданным макросом 従って、MT5のmq4コードを変更せずに動作させることは、必ずしも可能ではありません。 ドキュメントに変更はございません。もう少し詳しく説明してください。 fxsaber 2019.03.21 07:44 #1298 Alexey Viktorov:ドキュメントに変更はございません。もう少し詳しく説明してください。このようなコード #property script_show_inputs #define extern input // macro redefinition extern int i = 0; void OnStart() {}は常に警告を発生させます。ありえない」というのは、ちょっと厳しいですね。オーバーライドすることが可能なので、そのような状況では警告だけで必ずハングアップします。 Alexey Navoykov 2019.03.28 11:43 #1299 fxsaber:そのニュアンスのひとつがこれです。コンストラクタ/デストラクタを持つ構造体の配列を取る場合、どちらかの方向のArrayResizeは、値の差に等しい数でそれらを呼び出します。 しかし、ArrayCopyを適用すると、すべてのコンストラクタが呼び出されます。ArrayTmpの削除は、すべてのデストラクタの呼び出しになります。つまり、ArrayResize2 は本当の ArrayResize ではないのです。 ArrayReallocateと呼ぶべきかもしれませんが、このような強制的な再コピーに意味があるとは思えません。不必要な速度低下を招くことになる。唯一、クラスオブジェクトの 配列のポインタをリセットする(以前の値を無効にする)必要がある場合のみ、どこかに計上されていればいいのでしょう(でも、むしろひつような気もするのですが......)。 fxsaber 2019.03.28 13:34 #1300 Alexey Navoykov: それならArrayReallocateと呼ぶ方が正しいかもしれませんが、このような強制的な再コピーに意味があるとは思えません。不要なブレーキメモリを解放する ことが唯一の理由です。 1...123124125126127128129130131132133134135136137...247 新しいコメント 理由: キャンセル 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
ありがとうございます。ArraySwap関数を使うことは、私には思いつかなかったでしょう。
この関数は、サイズの増加と減少の両方、つまりArrayResizeの完全なアナログとして動作すると理解しています。
ArraySwap、ArrayResize、ArrayCopyの 3つの関数を呼び出すのではなく、配列が拡大されたときに標準のArrayResize関数を呼び出すだけでよいのではないでしょうか?
p.sMqlTickの 配列を1,000,000から500,0000に減らすときに、あなたのバージョンと私のバージョンを2つコピーしてテストしました。あなたのバージョンでは22ミリ秒です。私のは37-38でやってます。ArraySwap、ArrayResize、ArrayCopyの 3つの関数を呼び出すよりも、配列が大きくなったときに標準のArrayResizeを単純に呼び出す方が良いのではありませんか?
考えたけどやらなかったのは、実はもっと微妙なところがあるからです。だから、饒舌なバージョンにこだわることにしたんです。
その機微のひとつが、これです。コンストラクタ/デストラクタを持つ構造体の配列を取ると、ArrayResizeは値の差に等しい量だけ、どちらかの方向に呼び出します。
しかし、ArrayCopyを適用 すると、すべてのコンストラクタが呼び出されます。ArrayTmpの削除は、すべてのデストラクタの呼び出しになります。つまり、ArrayResize2 は本当の ArrayResize ではないのです。
最適化後、以下のようになります。
フレームモードのExpert Advisorをオフにして、標準モードで実行すると、最適化中に取得したのと同じデータが表示されます。
この方法なら、何度でもOptimizationの 結果に戻ることができます。
SZY フレームモードのターミナルで開いたチャートでは、Expert Advisorを実行することはできないんだ。そのため、標準モードで実行する場合は、フレームを開いていないチャートで実行する必要があります。
fxsaber:
extern теперь является жестко заданным макросом
従って、MT5のmq4コードを変更せずに動作させることは、必ずしも可能ではありません。
ドキュメントに変更はございません。もう少し詳しく説明してください。
ドキュメントに変更はございません。もう少し詳しく説明してください。
このようなコード
は常に警告を発生させます。ありえない」というのは、ちょっと厳しいですね。オーバーライドすることが可能なので、そのような状況では警告だけで必ずハングアップします。
そのニュアンスのひとつがこれです。コンストラクタ/デストラクタを持つ構造体の配列を取る場合、どちらかの方向のArrayResizeは、値の差に等しい数でそれらを呼び出します。
しかし、ArrayCopyを適用すると、すべてのコンストラクタが呼び出されます。ArrayTmpの削除は、すべてのデストラクタの呼び出しになります。つまり、ArrayResize2 は本当の ArrayResize ではないのです。
それならArrayReallocateと呼ぶ方が正しいかもしれませんが、このような強制的な再コピーに意味があるとは思えません。不要なブレーキ
メモリを解放する ことが唯一の理由です。