Вопросы по ООП в MQL5 - страница 70

 
Maxim Kuznetsov:

это называется "развёртываение цикла" и без всякого OO и шаблонов делается компилятором (по крайней мере должно). 

Если заглянуть в промежуточный код (в ассемблер), то будут просто подряд N операций вместо цикла.

А можете рассказать, что происходит при рекурсивном вызове функции?

 
Dmitry Fedoseev:

А можете рассказать, что происходит при рекурсивном вызове функции?

а там нету рекурсивного вызова целевых функций :-)

в приведённом по ссылке примере N:=const, рекурсия только при генерации кода из шаблона и та хвостовая. По ссылке хитрый изврат свернуть const-цикл в рекурсию шаблонов и назвать умным словом

если-бы макросы имели циклы это записывалось бы как-то так:

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

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

#endfor

и после макро-процессора развёртывалось бы в последовательность N принтов. (что собственно и произошло, только через шаблонные классы)

То есть фокус работает только если N известно на время компиляции

 
Maxim Kuznetsov:

а там нету рекурсивного вызова целевых функций :-)

в приведённом по ссылке примере N:=const, рекурсия только при генерации кода из шаблона и та хвостовая. По ссылке хитрый изврат свернуть const-цикл в рекурсию шаблонов и назвать умным словом

если-бы макросы имели циклы это записывалось бы как-то так:

#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, но соответствующая include-строка не генерируется.

 
fxsaber:

Проверять не буду, других задач полно. Но верится с трудом.

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

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

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

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

Это для маленькой структуры

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

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

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

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

Это для большой.

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; }
};
//+------------------------------------------------------------------+

судя по Вашему исследованию класс В будет медленнее выполняться если часто использовать поля структуры при расчетах? 

Причина обращения: