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

 

对不起,伙计们,在项目 设置中已经关闭了优化功能。

代码。

   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 сек.

随着优化的进行

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

随着优化是的,它是相反的,我已经检查过很多次了

 
Aleksandr Matveev:

你应该先学习基础知识,然后证明你的观点。如果你至少读过一本关于CPU和内存操作的书,你会明白这个结果,不需要任何测试。我已经给你提供了最巧妙的一个,如果你想在编程方面有一点进步,你一定要读一读。

内存和CPU有什么关系? 这是关于优化,你这个书生气的理论家)。

 
Igor Makanu:

这并不奇怪,你需要能够测试MQL中最简单的运算符和操作--我为什么要在测试中加入srand(GetTickCount())??

;)

顺便说一下,仔细看一下,你的循环中的结果 ,没有以任何方式考虑,这意味着它可以很容易地被编译器剪掉。

 
Alexey Navoykov:

顺便说一下,我仔细看了一下,你的循环中的结果 ,没有以任何方式考虑到,所以编译器可以很容易地把它删掉。

甚至删除了rand() - 它的编译器完美地内联了它,做了这样一个测试。

#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;  test(N,"1. s1=rand()",s1=(string)tst);
   string s2;  test(N,"2. s2=rand()",s2=(string)tst);
   string s3;  test(N,"3. s3=rand()",s3=(string)tst);
   string s4;  test(N,"4. s4=rand()",s4=(string)tst);
   string s5;  test(N,"5. s5=rand()",s5=(string)tst);

   test(N,"1. q=rand()",string q=(string)tst);
   test(N,"2. q=rand()",string q=(string)tst);
   test(N,"3. q=rand()",string q=(string)tst);
   test(N,"4. q=rand()",string q=(string)tst);
   test(N,"5. q=rand()",string q=(string)tst);
  }
//+------------------------------------------------------------------+

2019.08.18 11:55:41.457 SpeedTest (EURUSD,H1) 1. s1=rand(): loops=100000000 ms=7672

2019.08.18 11:55:49.085 SpeedTest (EURUSD,H1) 2. s2=rand(): loops=100000000 ms=7625

2019.08.18 11:55:56.796 SpeedTest (EURUSD,H1) 3. s3=rand(): loops=100000000 ms=7719

2019.08.18 11:56:04.495 SpeedTest (EURUSD,H1) 4. s4=rand(): loops=100000000 ms=7703

2019.08.18 11:56:12.113 SpeedTest (EURUSD,H1) 5. s5=rand(): loops=100000000 ms=7610

2019.08.18 11:56:17.695 SpeedTest (EURUSD,H1) 1. q=rand(): loops=100000000 ms=5578

2019.08.18 11:56:23.362 SpeedTest (EURUSD,H1) 2. q=rand(): loops=100000000 ms=5672

2019.08.18 11:56:28.970 SpeedTest (EURUSD,H1) 3. q=rand(): loops=100000000 ms=5609

2019.08.18 11:56:34.637 SpeedTest (EURUSD,H1) 4. q=rand(): loops=100000000 ms=5672

2019.08.18 11:56:40.277 SpeedTest (EURUSD,H1) 5. q=rand(): loops=100000000 ms=5640


 
Alexey Navoykov:

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

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

哈哈,哈哈...阿列克谢,你对论坛上的一个主要的OOP专家声称(姑且称之为 "你"),"OOP肯定是禁忌的"。

代码不应该根据编译器的特殊性进行调整,而应该根据自己的思维特点进行调整。在这种情况下,理论上,在循环内声明一个变量 会降低效率。因为根据惯例,每次都要创建变量,每次都要销毁。

这甚至不是效率的问题。坚实的代码是代码,它是透明的,清晰的,易于修改和维护。

我个人不喜欢有大量的变量散布在程序中,而且每次都要搜索某个特定变量的创建位置。 因此,如果可能的话,我尽量在函数的开头声明变量,所有的变量都在一起--只是为了看看它们在哪里被创建,了解它们何时被删除。

在这种情况下,这个例子只是非常短。当一个变量的创建和使用之间有几十行和一堆嵌套函数时--对我来说,当变量在块外提前声明时,就会更可靠。

 
pivalexander:

对不起,伙计们,在项目设置中已经关闭了优化功能。

代码。


未经优化的

随着优化的进行

对于优化,是的,它是相反的,我已经检查过很多次了。

在你的例子中,整个循环体都可以通过优化而被剪掉。

 

总的来说,这一切都像预期的那样,没有必要做无用功,寻找不存在的问题,制造真正的问题。

如果你心痒难耐,认为自己是个很酷的黑客,那就用汇编程序来写,否则就站在一边,让编译器做它的工作。

 
Aleksandr Matveev:

在这个例子中,你的整个循环体都可以通过优化而被剪掉。

用一个空的循环体执行的结果,非常不同,工作速度更快

Без оптимизации:
Test1, время выполнения: 0.027539 сек.

С оптимизацией:
Test1, время выполнения: 0.005448 сек.
 
Alexey Navoykov:

总的来说,这一切都像预期的那样,没有必要做无用功,寻找不存在的问题,制造真正的问题。

如果你心痒难耐,认为自己是个很酷的黑客,就用汇编程序来写。 否则就站在一边,让编译器做它的工作。

主要的问题恰恰是我不认为自己是一个很酷的黑客。这就是为什么变量,在我看来,应该在循环之外声明。而且更好的是--在功能的开始,一下子就有了。

而只是酷爱者可以根据需要,在代码内声明变量。

 
Georgiy Merts:

主要的问题恰恰是我不认为自己是一个很酷的黑客。这就是为什么变量,在我看来,应该在循环之外声明。 而且最好是在函数的开头,一次完成。

Koolhackers可以在代码中根据需要声明变量。

我更喜欢将我的代码分成逻辑块,并在这些块中声明所需的变量,而不是在一个函数的开头创建一堆变量,其中大部分只在一个块中需要,在远在下面的地方