mql5语言的特点、微妙之处以及技巧 - 页 130 1...123124125126127128129130131132133134135136137...247 新评论 fxsaber 2019.03.15 11: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 12:13 #1292 fxsaber: 谢谢你。使用ArraySwap函数,我不会想到。 我知道你的函数对增加和减少大小都有效,即作为ArrayResize的完全类似物。 当一个数组被放大时,简单地调用标准的ArrayResize函数,而不是调用ArraySwap、ArrayResize、ArrayCopy 这三个函数,这样不是更好吗? p.s 当把MqlTick 数组从1,000,000减少到500,0000时,用两个副本测试了你和我的版本。你的版本在22毫秒内完成。我家的在37-38岁时就这样了。 fxsaber 2019.03.15 12:29 #1293 pivomoe:当一个数组被扩大时,简单地调用标准的ArrayResize不是比调用三个函数ArraySwap,ArrayResize,ArrayCopy 更好吗?我想过这个问题,但没有做,因为实际上有更多的微妙之处。这就是为什么我决定坚持使用简洁的版本。 其中一个微妙之处在于此。如果你拿一个有构造函数/解构函数的结构数组,ArrayResize将在任何一个方向上调用它们,其数量等于数值的差异。 但应用ArrayCopy 是在调用所有构造函数。删除ArrayTmp是对所有析构器的调用。所以ArrayResize2并不是真正的ArrayResize。 pivomoe 2019.03.15 14:42 #1294 事实证明,你可以像这样写ArrayResize( arr, new_size, -1)。但你的版本仍然更快,约22毫秒对37毫秒。 fxsaber 2019.03.17 19:00 #1295 可能发生的情况是,你脱离了EA的框架模式,需要重新进入该模式。下面的专家顾问显示了如何做到这一点// Создание 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 如果你在框架模式下关闭专家顾问,并在标准模式下运行,它将显示在优化期间得到的相同数据。 这种方法允许你多次回到优化结果中 去。 SZY 在终端打开的框架模式的图表上,你不能运行任何专家顾问。因此,如果你想在标准模式下运行它,你应该在一个没有打开过框架的图表上运行它。 fxsaber 2019.03.21 08:14 #1296 现在extern是一个硬编码的宏#undef extern #define extern // macro redefinition 相应地,不可能总是让MT5的mq4代码不经修改就能工作。 Alexey Viktorov 2019.03.21 08:22 #1297 fxsaber: extern теперь является жестко заданным макросом 相应地,不可能总是让MT5的mq4代码不经修改就能工作。 文件中没有任何变化。你能更详细地解释这个问题吗? fxsaber 2019.03.21 08:44 #1298 Alexey Viktorov:文件中没有任何变化。你能更详细地解释这个问题吗?这样的代码 #property script_show_inputs #define extern input // macro redefinition extern int i = 0; void OnStart() {}将总是产生一个警告。我对 "不可能 "的说法有点苛刻。有可能被覆盖,所以在这种情况下,只是一个警告会一直挂着。 Alexey Navoykov 2019.03.28 12:43 #1299 fxsaber:其中一个细微差别是这样的。如果你拿一个有构造函数/解构函数的结构数组,那么ArrayResize在任何一个方向上调用它们的数量都等于数值的差异。 但应用ArrayCopy是在调用所有构造函数。删除ArrayTmp是对所有析构器的调用。所以ArrayResize2并不是真正的ArrayResize。 也许它应该被称为ArrayReallocate,尽管我不认为这种强制的重新复制有任何意义。这将导致不必要的速度减慢。唯一的可能是只有在需要为类对象 的数组重置指针时(使它们之前的值无效),如果在某个地方有交代的话(但这是相当的拐杖)。 fxsaber 2019.03.28 14:34 #1300 Alexey Navoykov: 那么把它称为ArrayReallocate可能更正确,尽管我不认为这种强制重写有任何意义。不必要的制动。释放内存 是唯一的原因。 1...123124125126127128129130131132133134135136137...247 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
谢谢你。使用ArraySwap函数,我不会想到。
我知道你的函数对增加和减少大小都有效,即作为ArrayResize的完全类似物。
当一个数组被放大时,简单地调用标准的ArrayResize函数,而不是调用ArraySwap、ArrayResize、ArrayCopy 这三个函数,这样不是更好吗?
p.s 当把MqlTick 数组从1,000,000减少到500,0000时,用两个副本测试了你和我的版本。你的版本在22毫秒内完成。我家的在37-38岁时就这样了。当一个数组被扩大时,简单地调用标准的ArrayResize不是比调用三个函数ArraySwap,ArrayResize,ArrayCopy 更好吗?
我想过这个问题,但没有做,因为实际上有更多的微妙之处。这就是为什么我决定坚持使用简洁的版本。
其中一个微妙之处在于此。如果你拿一个有构造函数/解构函数的结构数组,ArrayResize将在任何一个方向上调用它们,其数量等于数值的差异。
但应用ArrayCopy 是在调用所有构造函数。删除ArrayTmp是对所有析构器的调用。所以ArrayResize2并不是真正的ArrayResize。
优化后,你会看到以下内容
如果你在框架模式下关闭专家顾问,并在标准模式下运行,它将显示在优化期间得到的相同数据。
这种方法允许你多次回到优化结果中 去。
SZY 在终端打开的框架模式的图表上,你不能运行任何专家顾问。因此,如果你想在标准模式下运行它,你应该在一个没有打开过框架的图表上运行它。
fxsaber:
extern теперь является жестко заданным макросом
相应地,不可能总是让MT5的mq4代码不经修改就能工作。
文件中没有任何变化。你能更详细地解释这个问题吗?
文件中没有任何变化。你能更详细地解释这个问题吗?
这样的代码
将总是产生一个警告。我对 "不可能 "的说法有点苛刻。有可能被覆盖,所以在这种情况下,只是一个警告会一直挂着。
其中一个细微差别是这样的。如果你拿一个有构造函数/解构函数的结构数组,那么ArrayResize在任何一个方向上调用它们的数量都等于数值的差异。
但应用ArrayCopy是在调用所有构造函数。删除ArrayTmp是对所有析构器的调用。所以ArrayResize2并不是真正的ArrayResize。
那么把它称为ArrayReallocate可能更正确,尽管我不认为这种强制重写有任何意义。不必要的制动。
释放内存 是唯一的原因。