在循环后面声明变量还是在循环里面声明变量? - 页 2

 
Georgiy Merts:

不,我没有。

当然,在这种情况下,一个正常的编译器应该把循环内的变量声明带到外部。

我只是认为你应该永远相信编译器,相信自己。编译器的标准是,局部变量在声明时被创建,在声明它的块退出时被删除。因此,你应该首先关注这一原则,而不是等待编译器为你改进你的代码。

所以我说,如果你想 "做得更好",就去做汇编,如果你需要自己控制一切......毕竟,你刚才描述的情况根本就不算什么。还有更复杂的事情。 OOP对你来说绝对是禁忌。你不会知道编译器是否将某个特定的虚拟方法退化成了一个普通的调用,或者是否削减了一个不必要的指针检查......在这样的偏执下,你能在管理的MQL中做什么?)

而为了适应编译器的特殊性(而且是想象中的特殊性)而调整代码,损害代码的正确性和可靠性,显然不是一个好的程序员应该做的。 而这里我们谈论的正是代码的不正确性。 变量必须直接在使用它的块中声明。

 
Vict:

伙计,这简直是疯狂的愚蠢,有什么可评论的,完全不了解调试器的工作原理。

你会的。
[删除]  
Alexey Navoykov:
你会的。

就像在幼儿园一样)))我为那些在坦克里的人解释一下:首先我们编译g++ 1.cpp,那里没有断点,编译器对断点一无所知。然后运行调试器:gdb a.out,现在才放断点

你明白你说的是什么胡话吗?

 
Alexey Navoykov:

你只能通过编译代码或测量其性能来检测优化。 这是你应该做的第一件事。冷静下来 )

2019.08.18 10:28:12.826 SpeedTest (EURUSD,H1) 1. s1=rand(): loops=100000000 ms=7031

2019.08.18 10:28:19.885 SpeedTest (EURUSD,H1) 2. s2=rand(): loops=100000000 ms=7063

2019.08.18 10:28:27.037 SpeedTest (EURUSD,H1) 3. s3=rand(): loops=100000000 ms=7140

2019.08.18 10:28:34.045 SpeedTest (EURUSD,H1) 4. s4=rand(): loops=100000000 ms=7016

2019.08.18 10:28:41.135 SpeedTest (EURUSD,H1) 5. s5=rand(): loops=100000000 ms=7094

2019.08.18 10:28:47.896 SpeedTest (EURUSD,H1) 1. q=rand(): loops=100000000 ms=6750

2019.08.18 10:28:54.659 SpeedTest (EURUSD,H1) 2. q=rand(): loops=100000000 ms=6765

2019.08.18 10:29:01.447 SpeedTest (EURUSD,H1) 3. q=rand(): loops=100000000 ms=6797

2019.08.18 10:29:08.257 SpeedTest (EURUSD,H1) 4. q=rand(): loops=100000000 ms=6797

2019.08.18 10:29:15.102 SpeedTest (EURUSD,H1) 5. q=rand(): loops=100000000 ms=6844

//+------------------------------------------------------------------+
//|                                                    SpeedTest.mq5 |
//|                                                            IgorM |
//|                              https://www.mql5.com/ru/users/igorm |
//+------------------------------------------------------------------+
#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#define  N 8

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

   srand(GetTickCount()); test(N,"1. q=rand()",string q=IntegerToString(rand()));
   srand(GetTickCount()); test(N,"2. q=rand()",string q=IntegerToString(rand()));
   srand(GetTickCount()); test(N,"3. q=rand()",string q=IntegerToString(rand()));
   srand(GetTickCount()); test(N,"4. q=rand()",string q=IntegerToString(rand()));
   srand(GetTickCount()); test(N,"5. q=rand()",string q=IntegerToString(rand()));
  }
//+------------------------------------------------------------------+
[删除]  
我在调试器下挖出了类似的代码,但没有用户操作符新,好吧,可能有一些疑问--用户操作符没有被优化。捕获了libc对malloc()的调用。结果是:循环中的字符串--每次打印前的一次调用,循环外的--一批打印前的一次调用。毋庸置疑,只有第一种变体更好。当然,有可能在μl中有些东西是不同的,但最好是由成熟的语言来指导。
 
#define  N 9

2019.08.18 10:37:59.620 SpeedTest (EURUSD,H1) 1. s1=rand(): loops=1000000000 ms=70672

2019.08.18 10:39:10.352 SpeedTest (EURUSD,H1) 2. s2=rand(): loops=1000000000 ms=70719

2019.08.18 10:40:21.908 SpeedTest (EURUSD,H1) 3. s3=rand(): loops=1000000000 ms=71562

2019.08.18 10:41:32.315 SpeedTest (EURUSD,H1) 4. s4=rand(): loops=1000000000 ms=70407

2019.08.18 10:42:42.996 SpeedTest (EURUSD,H1) 5. s5=rand(): loops=1000000000 ms=70687

2019.08.18 10:43:50.964 SpeedTest (EURUSD,H1) 1. q=rand(): loops=1000000000 ms=67969

2019.08.18 10:44:58.887 SpeedTest (EURUSD,H1) 2. q=rand(): loops=1000000000 ms=67922

2019.08.18 10:46:06.829 SpeedTest (EURUSD,H1) 3. q=rand(): loops=1000000000 ms=67937

2019.08.18 10:47:14.602 SpeedTest (EURUSD,H1) 4. q=rand(): loops=1000000000 ms=67766

2019.08.18 10:48:22.428 SpeedTest (EURUSD,H1) 5. q=rand(): loops=1000000000 ms=67828

 

Igor Makanu:

#define    test(M,S,EX) {uint mss=GetTickCount();ulong nn=(ulong)pow(10,M);for(ulong tst=0;tst<nn&&!_StopFlag;tst++){EX;} \

伙计,"空格键 "对你不起作用吗?这不是我第一次注意到,还是你在硬盘上保存了字节数?)

 
Alexey Navoykov:

你在开玩笑吗? 对于编译器来说,这是一个微不足道的情况,没有什么可谈的。 你不能对它如此偏执,而只是用汇编程序编码。 ) 虽然现在连这也变得毫无意义了。 你必须努力去打败现代编译器的优化。

p.s. 也许我在这里对琐事有点激动,因为我在谈论字符串缓冲区。但在MQL中,不仅在循环内部,甚至在函数调用之间,它都能保证被保存。这个话题在这里不止一次讨论过

我怀疑这个声明的作者根本不知道处理器、内存和编译器是如何工作的......我敢打赌,你的任何代码都可以被加速至少十倍,甚至几百倍。 由于这种低劣的编码员,现在大多数产品在有几十个核心的强大计算机上都慢得令人难以忍受,而你只需要思考一下...但有些人认为,"为什么要思考?你必须要编码......"

供你参考,目前没有一个编译器学会理解程序员想得到的结果。它可以解开一些循环,优化一些内存访问,将数据保存在处理器的缓存中,但如果代码一开始就没有被优化,而且是通过一个地方写的,那么没有编译器可以帮助你...

P.S. 闲暇时阅读克里斯-卡巴斯基的一本有趣的书《程序优化技术》。高效的内存使用"。

 
Alexey Volchanskiy:

乔治是对的,这并不保证。

我们得到了一个从'数字'到'字符串'的翘曲隐式转换


而这正是你摆脱模糊性和扭曲性的方法。

for (int i = 0; i < 1000; i++)
   {
      static string st = IntegerToString(i);
      ...
   }

这就是我一直以来的做法。

string st = (string)i;

静态的意义何在? 赋值在第一次迭代中只起一次作用。


我决定衡量一下执行的速度。

   CStopWatch sw; // Секундомер, для замера времени
   
   sw.Start();
   for (int i = 0; i < 10000000; i++)
   {
      string st = (string)i;
   }
   pr("Test1, время выполнения: " + sw.Stop());

   sw.Start();
   string st = "";
   for (int i = 0; i < 10000000; i++)
   {
      st = (string)i;
   }
   pr("Test2, Время выполнения: " + sw.Stop());

其结果是。

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

运行了很多次,结果是稳定的,在循环后声明一个变量 的代码,工作得更快。

 
Alexey Navoykov:

伙计,"空格键 "对你不起作用吗?这不是我第一次注意到,还是你在硬盘上保存了字节数?)

不,这段代码不是我的,我对它进行了一些改进--我从关于 "搜索分号 "的主题中为自己复制了代码,并将其用于有争议的问题,我懒得去改变它。

我有空间,但我懒得去做 ))))

ZS:给我一个模型代码,我把它复制到自己身上,将来就像你想的那样,我原则上不打扰。

ZS:这里是AD。

#define    test(M,S,EX) {                                 \
uint mss=GetTickCount();                                 \
ulong nn=(ulong)pow(10,M);                               \
for(ulong tst=0;tst<nn && !_StopFlag;tst++) \
{ EX; }                                                  \
printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}