MQL5中的OOP问题 - 页 70

 
Maxim Kuznetsov:

这被称为 "循环解卷",由编译器完成,没有任何OO和模板(至少应该如此)。

如果你看一下中间代码(汇编程序),只是有连续的N个操作,而不是一个循环。

你能告诉我们当一个函数被递归调用 时会发生什么吗?

 
Dmitry Fedoseev:

你能告诉我当一个函数被递归调用 时会发生什么吗?

不存在对目标函数的递归调用 :-)

在上面给定的例子中,N:=const,递归只发生在从模板生成代码时,并且该模板是定制的。在链接处,一个巧妙的转折是将const-cycle折叠成模板递归,并将其称为一个巧妙的词

如果宏有循环,它应该这样写

#for x=0, x<N, x++

print("x=%d",x);

#endfor

而在宏观处理器之后,它将展开成一个N个王子的序列。(这实际上已经发生了,只是通过模板类)

也就是说,只有在编译时知道N的情况下,这个技巧才有效

 
Maxim Kuznetsov:

并且没有对目标函数的递归调用 :-)

在链接N:=const给出的例子中,递归只是在从模板中生成代码时才有的,而且这个模板是定制的。在链接处,一个巧妙的转折是将const-cycle折叠成模板递归,并将其称为一个巧妙的词

如果宏有循环,它应该这样写

#for x=0, x<N, x++

print("x=%d",x);

#endfor

而在宏观处理器之后,它将展开成一个N个王子的序列。(这实际上已经发生了,只是通过模板类)

因此,只有在编译时知道N的情况下,这一招才有效

你不会相信的,但我知道模板是如何工作的,有什么N种情况,结果是什么。而我关于递归函数调用的 问题正是关于递归函数调用,而不是关于如何有?

 
Dmitry Fedoseev:

你不会相信,但我知道模板是如何工作的,以及N是什么,结果是什么。而我关于递归函数调用的 问题正是关于递归函数调用,而不是关于如何有?

它就像一个 "敢不敢?"的考试吗?:-) 我莫名其妙地以为这个例子正在被讨论......我错了 :-)

如果编译器可以将递归转换为尾部(或者明确是这样的,或者他被告知这样做),那么在物理上将没有递归--它将做一个循环(切换回来),每次迭代将 "践踏 "前一个堆栈帧。

 
Maxim Kuznetsov:

这是某种 "挑战 "考试吗?:-) 我莫名其妙地以为这个例子正在被讨论......我错了 :-)

如果编译器可以将递归转换为尾部递归(或者明确地这样做,或者被告知这样做),那么物理上将没有递归--它将做一个循环(切换回来),每个迭代将 "践踏 "前一个堆栈帧。

这与软弱有什么关系?只是一个问题。嗯,没有,所以没有。

 
fxsaber:

我甚至不想去打扰。我做了简单的结构。



出于什么原因,对一个简单结构的第一个字段的访问取决于其大小--我不明白。

嗯。这是微不足道的--要乘以的位数更多))))。确保结构大小 的二进制表示法中的比特数是相同的))))愚蠢的处理器,以及一个人,更长的时间来乘以1111*101比1111*10)
 
Vladimir Simakov:
嗯。这是微不足道的--乘法的比特数为更多))))确保结构大小 的二进制表示法中的比特数是相同的)))愚蠢的处理器,以及一个人,更长的时间来乘以1111*101比1111*10)

我不会检查,还有很多其他的任务。但我觉得这很难让人相信。

 

在ME中,我用mqh工作,按ALT+N--导航窗口中的树状视图显示文件的位置。

现在我想让它嵌入打开mq5-文件。我把mqh从树上拖到mq5,但没有产生适当的包含行。

 
fxsaber:

我不会检查,还有很多其他的任务。但我觉得这很难让人相信。

template <typename T>
size_t Func(T* arr,size_t arrSize)
{
000000013 FFC1DA0  mov         qword ptr [rsp+10 h],rdx  
000000013 FFC1DA5  mov         qword ptr [rsp+8],rcx  
000000013 FFC1DAA  push        rbp  
000000013 FFC1DAB  push        rdi  
000000013 FFC1DAC  sub         rsp,148 h  
000000013 FFC1DB3  lea         rbp,[rsp+20 h]  
000000013 FFC1DB8  mov         rdi,rsp  
000000013 FFC1DBB  mov         ecx,52 h  
000000013 FFC1DC0  mov         eax,0 CCCCCCCCh  
000000013 FFC1DC5  rep stos    dword ptr [rdi]  
000000013 FFC1DC7  mov         rcx,qword ptr [rsp+168 h]  
000000013 FFC1DCF  lea         rcx,[__116109BC_Test@cpp (013 FFD5029h)]  
000000013 FFC1DD6  call        __CheckForDebuggerJustMyCode (013 FFC10B9h)  
    // Write
    for (size_t i = 0; i <arrSize; ++i)
000000013 FFC1DDB  mov         qword ptr [rbp+8],0  
000000013 FFC1DE3  jmp         Func<STRUCT1>+50 h (013 FFC1DF0h)  
000000013 FFC1DE5  mov         rax,qword ptr [rbp+8]  
000000013 FFC1DE9  inc         rax  
000000013 FFC1DEC  mov         qword ptr [rbp+8],rax  
000000013 FFC1DF0  mov         rax,qword ptr [arrSize]  
000000013 FFC1DF7  cmp         qword ptr [rbp+8],rax  
000000013 FFC1DFB  jae         Func<STRUCT1>+71 h (013 FFC1E11h)  
        arr[i].i = i;
000000013 FFC1DFD  imul        rax,qword ptr [rbp+8],18 h  
000000013 FFC1E02  mov         rcx,qword ptr [arr]  
000000013 FFC1E09  mov         edx,dword ptr [rbp+8]  
000000013 FFC1E0C  mov         dword ptr [rcx+rax],edx  
000000013 FFC1E0F  jmp         Func<STRUCT1>+45 h (013 FFC1DE5h)  

    size_t Sum = 0;
000000013 FFC1E11  mov         qword ptr [Sum],0  

    // Read
    for (size_t i = 0; i < arrSize; ++i)
000000013 FFC1E19  mov         qword ptr [rbp+48 h],0  
000000013 FFC1E21  jmp         Func<STRUCT1>+8 Eh (013 FFC1E2Eh)  
000000013 FFC1E23  mov         rax,qword ptr [rbp+48 h]  
000000013 FFC1E27  inc         rax  
000000013 FFC1E2A  mov         qword ptr [rbp+48 h],rax  
000000013 FFC1E2E  mov         rax,qword ptr [arrSize]  
000000013 FFC1E35  cmp         qword ptr [rbp+48 h],rax  
000000013 FFC1E39  jae         Func<STRUCT1>+0 BBh (013 FFC1E5Bh)  
        Sum += arr[i].i;
000000013 FFC1E3B  imul        rax,qword ptr [rbp+48 h],18 h  
000000013 FFC1E40  mov         rcx,qword ptr [arr]  
000000013 FFC1E47  movsxd      rax,dword ptr [rcx+rax]  
000000013 FFC1E4B  mov         rcx,qword ptr [Sum]  
000000013 FFC1E4F  add         rcx,rax  
000000013 FFC1E52  mov         rax,rcx  
000000013 FFC1E55  mov         qword ptr [Sum],rax  
000000013 FFC1E59  jmp         Func<STRUCT1>+83 h (013 FFC1E23h)  

    return Sum + arrSize;
000000013 FFC1E5B  mov         rax,qword ptr [arrSize]  
000000013 FFC1E62  mov         rcx,qword ptr [Sum]  
000000013 FFC1E66  add         rcx,rax  
000000013 FFC1E69  mov         rax,rcx  
}
000000013 FFC1E6C  lea         rsp,[rbp+128 h]  

这是为一个小的结构。

template <typename T>
size_t Func(T* arr,size_t arrSize)
{
000000013 FFC1EB0  mov         qword ptr [rsp+10 h],rdx  
000000013 FFC1EB5  mov         qword ptr [rsp+8],rcx  
000000013 FFC1EBA  push        rbp  
000000013 FFC1EBB  push        rdi  
000000013 FFC1EBC  sub         rsp,148 h  
000000013 FFC1EC3  lea         rbp,[rsp+20 h]  
000000013 FFC1EC8  mov         rdi,rsp  
000000013 FFC1ECB  mov         ecx,52 h  
000000013 FFC1ED0  mov         eax,0 CCCCCCCCh  
000000013 FFC1ED5  rep stos    dword ptr [rdi]  
000000013 FFC1ED7  mov         rcx,qword ptr [rsp+168 h]  
000000013 FFC1EDF  lea         rcx,[__116109BC_Test@cpp (013 FFD5029h)]  
000000013 FFC1EE6  call        __CheckForDebuggerJustMyCode (013 FFC10B9h)  
    // Write
    for (size_t i = 0; i <arrSize; ++i)
000000013 FFC1EEB  mov         qword ptr [rbp+8],0  
000000013 FFC1EF3  jmp         Func<STRUCT3>+50 h (013 FFC1F00h)  
000000013 FFC1EF5  mov         rax,qword ptr [rbp+8]  
000000013 FFC1EF9  inc         rax  
000000013 FFC1EFC  mov         qword ptr [rbp+8],rax  
000000013 FFC1F00  mov         rax,qword ptr [arrSize]  
000000013 FFC1F07  cmp         qword ptr [rbp+8],rax  
000000013 FFC1F0B  jae         Func<STRUCT3>+71 h (013 FFC1F21h)  
        arr[i].i = i;
000000013 FFC1F0D  imul        rax,qword ptr [rbp+8],58 h  
000000013 FFC1F12  mov         rcx,qword ptr [arr]  
000000013 FFC1F19  mov         edx,dword ptr [rbp+8]  
000000013 FFC1F1C  mov         dword ptr [rcx+rax],edx  
000000013 FFC1F1F  jmp         Func<STRUCT3>+45 h (013 FFC1EF5h)  

    size_t Sum = 0;
000000013 FFC1F21  mov         qword ptr [Sum],0  

    // Read
    for (size_t i = 0; i < arrSize; ++i)
000000013 FFC1F29  mov         qword ptr [rbp+48 h],0  
000000013 FFC1F31  jmp         Func<STRUCT3>+8 Eh (013 FFC1F3Eh)  
000000013 FFC1F33  mov         rax,qword ptr [rbp+48 h]  
000000013 FFC1F37  inc         rax  
000000013 FFC1F3A  mov         qword ptr [rbp+48 h],rax  
000000013 FFC1F3E  mov         rax,qword ptr [arrSize]  
000000013 FFC1F45  cmp         qword ptr [rbp+48 h],rax  
000000013 FFC1F49  jae         Func<STRUCT3>+0 BBh (013 FFC1F6Bh)  
        Sum += arr[i].i;
000000013 FFC1F4B  imul        rax,qword ptr [rbp+48 h],58 h  
000000013 FFC1F50  mov         rcx,qword ptr [arr]  
000000013 FFC1F57  movsxd      rax,dword ptr [rcx+rax]  
000000013 FFC1F5B  mov         rcx,qword ptr [Sum]  
000000013 FFC1F5F  add         rcx,rax  
000000013 FFC1F62  mov         rax,rcx  
000000013 FFC1F65  mov         qword ptr [Sum],rax  
000000013 FFC1F69  jmp         Func<STRUCT3>+83 h (013 FFC1F33h)  

    return Sum + arrSize;
000000013 FFC1F6B  mov         rax,qword ptr [arrSize]  
000000013 FFC1F72  mov         rcx,qword ptr [Sum]  
000000013 FFC1F76  add         rcx,rax  
000000013 FFC1F79  mov         rax,rcx  
}
000000013 FFC1F7C  lea         rsp,[rbp+128 h]  

这是为一个大的。

VS2019,Debug x64,在发布版中,它内联了它们,但速度是一样的。

唯一的区别是在imul指令中,第三个操作数,在两个地方。该指令只是计算数组中的偏移量,第三个操作数是结构的大小,单位是字节。

因此,没有神秘主义--物理学规律在起作用。

 
Vladimir Simakov:

因此,没有神秘主义--物理学定律在起作用。

如果你写了这样的类。

//+------------------------------------------------------------------+
struct STRUCT
{
   int i;
   double d;
   uchar uc[16];
};
//+------------------------------------------------------------------+
class A
{
private:
   int i;
   double d;
   uchar uc[16];
public:
   A(const STRUCT &ini) { i = ini.i; d = ini.d; ArrayCopy(uc,ini.uc); }
};
//+------------------------------------------------------------------+
class B
{
private:
   STRUCT data;
public:
   B(const STRUCT &ini) { data = ini; }
};
//+------------------------------------------------------------------+

根据你的研究判断,如果你在计算中频繁使用结构字段,B类的 执行速度会比较慢?