Интересное мнение про ООП - страница 8

 
fxsaber:

Пишу так, потому что нравится. При этом при отладке все становится очень плохо.


Даже в таком выражении

тяжело понять, кто и что возвращал. В более сложных (постоянно практикую) - совсем тяжко.

использовать в качестве возвращаемого значения 2-3... ну пусть 5 результатов выполнения функций объединенные логическими операциями (или условный тернарный оператор) - видел такое на гитхабе или еще где, с таким кодом разобраться можно

но если этого "добра" с десяток другой... имхо, это не практично 

 
Maxim Kuznetsov:

я конечно далеко не разработчик mql,

но в C switch порождает довольно эффективный бинарный поиск и не вызывает лишних подкачек страниц и не сбивает кеши. То есть да, он часто лучше косвенной адресации через массивы и структуры

где то писали и тут разработчики похожую информацию

нашел только это:

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Изучаем и пишем вместе на MQL5

Slava, 2011.04.14 09:59

Нет, к сожалению не будет. Для строковых типов только if ... else if ... else

За счёт использования целых типов в switch достигается нескольки кратное ускорение по сравнению с if 


 
Igor Makanu:

но если этого "добра" с десяток другой... имхо, это не практично

Маленький монстр.

  static bool VirtualOrderSelect( const TICKET_TYPE Index, const int Select, const int Pool = MODE_TRADES )
  {
    return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.OrderSelect(Index, Select, Pool) :
           #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
             VIRTUAL::SnapshotPtr ?
             #ifdef __MQL5__ // Выбор по тикету в MT5 - разнообразный набор вариантов.
               (Select == SELECT_BY_TICKET) ? ::OrderSelect(Index, Select, Pool) && VIRTUAL::SnapshotPtr.CopyOrder()
                                            :
             #endif // #ifdef __MQL5__
                                              ((((Index == INT_MIN) || (Index == INT_MAX)) && (Pool == MODE_TRADES) &&
                                               ::OrderSelect(Index, Select, Pool) &&
                                             #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY
                                               VIRTUAL::SnapshotPtr.CopyOrder(true))
                                             #else // #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY
                                               VIRTUAL::SnapshotPtr.CopyOrder())
                                             #endif // #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY #else
                                               || VIRTUAL::SnapshotPtr.OrderSelect(Index, Select, Pool))
                                  :
           #endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
           #ifdef __MQL5__
             #ifdef __MT4ORDERS__
               ::OrderSelect(Index, Select, Pool)
             #else // __MT4ORDERS__
               false
             #endif // __MT4ORDERS__
           #else // __MQL5__
             ::OrderSelect(Index, Select, Pool)
           #endif // __MQL5__
           );
  }

логические операции позволяют лаконично писать при использовании различных настроек через макросы. Но это ужас, конечно.

 
fxsaber:

логические операции позволяют лаконично писать при использовании различных настроек через макросы. Но это ужас, конечно.

Ваш пример из "цель оправдывает средства"

мой вопрос был про совсем другой и непонятный мне стиль

 
fxsaber:

Маленький монстр.

Дарёному коню в зубы не смотрят. Но вот ещё пара примеров чужого кода, которые доставили мне несколько незабываемых десятков минут отладки. Возможно, кто-то узнает свой код.

      Res = (!FillingMode || (Type >= ORDER_FILLING_RETURN) || ((FillingMode & (Type + 1)) != Type + 1)) ?
            (((ExeMode == SYMBOL_TRADE_EXECUTION_EXCHANGE) || (ExeMode == SYMBOL_TRADE_EXECUTION_INSTANT)) ?
             ORDER_FILLING_RETURN : ((FillingMode == SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) :
            (ENUM_ORDER_TYPE_FILLING)Type;
    return((arrow_color == INT_MAX) ? (MT4ORDERS::NewOrderCheck() ? 0 : -1) :
           ((((int)arrow_color != INT_MIN) || MT4ORDERS::NewOrderCheck()) &&
            MT4ORDERS::OrderSend(MT4ORDERS::LastTradeRequest, MT4ORDERS::LastTradeResult) ?
            (MT4ORDERS::IsHedging ? (long)MT4ORDERS::LastTradeResult.order : // PositionID == Result.order - особенность MT5-Hedge
             ((MT4ORDERS::LastTradeRequest.action == TRADE_ACTION_DEAL) ?
              (MT4ORDERS::IsTester ? (_B2(::PositionSelect(MT4ORDERS::LastTradeRequest.symbol)) ? PositionGetInteger(POSITION_TICKET) : 0) :
                                      // HistoryDealSelect в MT4ORDERS::OrderSend
                                      ::HistoryDealGetInteger(MT4ORDERS::LastTradeResult.deal, DEAL_POSITION_ID)) :
              (long)MT4ORDERS::LastTradeResult.order)) : -1));

Не знаю, было ли легко его так писать, но отлаживать, а тем более просто читать, его малореально. И объективных причин именно так написать не вижу.

 
traveller00:

И объективных причин именно так написать не вижу.

Они субъективны, конечно. Не люблю лишние переменные и несколько return. По какой-то причине считаю, что без них EX5 будет короче и выполняться быстрее.

 
fxsaber:

Они субъективны, конечно. Не люблю лишние переменные и несколько return. По какой-то причине считаю, что без них EX5 будет короче и выполняться быстрее.

кстати вот эта уверенность что код будет короче и быстрее - не факт что оправдана.

вот это

bool a=A();
bool b=B();
//....много промежуточных результатов
bool x=X();
bool Res=a||b||x ;
return Res;

и вот это

return A()||B()||X();

уверен будет одинаково по скорости (возможно и объему кода и использованной памяти)

Просто второй вариант быстрее написать, и все пишут его, а потом когда надо что-то добавить/усложнить, так и оставляют второй вариант, только уже раздутый до сложно-читаемого.

Периодически делать рефакторинг в этом плане - и не будет проблем.

 
Aleksey Mavrin:

Периодически делать рефакторинг в этом плане - и не будет проблем.

Только для тех, у кого уйма свободного времени или объективно прижало настолько, что никуда не деться без этого.

ЗЫ Когда много return, код 100% будет иным.
 
fxsaber:

Только для тех, у кого уйма свободного времени или объективно прижало настолько, что никуда не деться без этого.

ЗЫ Когда много return, код 100% будет иным.

понимаю, но частично согласен, просто думаю все сталкивались с относительно долгим отловом ошибок, которые бы нашлись быстрее будь код "идеально готовым" для отладки.

Неизвестно что съедает времени больше - более долгое написание "удобного" кода  или отладка и поиск багов, всегда по разному думаю.

 
fxsaber:

ЗЫ Когда много return, код 100% будет иным.

C++ VS2019 под отладчиком

исходник:

bool a(int v) { return(v > 0); }
bool b(int v) { return(v < 0); }
bool c(int v) { return(v == 0);}

bool tst1(int v1, int v2, int v3)
{
        if (a(v1)) return(true);
        if (b(v2)) return(true);
        if (c(v3)) return(true);
        return(false);
}

bool tst2(int v1, int v2, int v3)
{
        return(a(v1) && b(v2) && c(v3));
}

int main()
{
        int x = 1, y=2, z=3;
        bool result1 = tst1(x, y, z);
        bool result2 = tst2(x, y, z);
}

отладчик в asm

bool tst1(int v1, int v2, int v3)
{
        if (a(v1)) return(true);
000E1918  mov         eax,dword ptr [v1]  
000E191B  push        eax  
000E191C  call        a (0E137Ah)  
000E1921  add         esp,4  
000E1924  movzx       ecx,al  
000E1927  test        ecx,ecx  
000E1929  je          tst1+3Fh (0E192Fh)  
000E192B  mov         al,1  
000E192D  jmp         tst1+6Fh (0E195Fh)  
        if (b(v2)) return(true);
000E192F  mov         eax,dword ptr [v2]  
000E1932  push        eax  
000E1933  call        b (0E13ACh)  
000E1938  add         esp,4  
000E193B  movzx       ecx,al  
000E193E  test        ecx,ecx  
000E1940  je          tst1+56h (0E1946h)  
000E1942  mov         al,1  
000E1944  jmp         tst1+6Fh (0E195Fh)  
        if (c(v3)) return(true);
000E1946  mov         eax,dword ptr [v3]  
000E1949  push        eax  
000E194A  call        c (0E11B8h)  
000E194F  add         esp,4  
000E1952  movzx       ecx,al  
000E1955  test        ecx,ecx  
000E1957  je          tst1+6Dh (0E195Dh)  
000E1959  mov         al,1  
000E195B  jmp         tst1+6Fh (0E195Fh)  
        return(false);
000E195D  xor         al,al  
}


bool tst2(int v1, int v2, int v3)
{
        return(a(v1) && b(v2) && c(v3));
000E19C8  mov         eax,dword ptr [v1]  
000E19CB  push        eax  
000E19CC  call        a (0E137Ah)  
000E19D1  add         esp,4  
000E19D4  movzx       ecx,al  
000E19D7  test        ecx,ecx  
000E19D9  je          tst2+6Dh (0E1A0Dh)  
000E19DB  mov         edx,dword ptr [v2]  
000E19DE  push        edx  
000E19DF  call        b (0E13ACh)  
000E19E4  add         esp,4  
000E19E7  movzx       eax,al  
000E19EA  test        eax,eax  
000E19EC  je          tst2+6Dh (0E1A0Dh)  
000E19EE  mov         ecx,dword ptr [v3]  
000E19F1  push        ecx  
000E19F2  call        c (0E11B8h)  
000E19F7  add         esp,4  
000E19FA  movzx       edx,al  
000E19FD  test        edx,edx  
000E19FF  je          tst2+6Dh (0E1A0Dh)  
000E1A01  mov         dword ptr [ebp-0C4h],1  
000E1A0B  jmp         tst2+77h (0E1A17h)  
000E1A0D  mov         dword ptr [ebp-0C4h],0  
000E1A17  mov         al,byte ptr [ebp-0C4h]  
}



свел по командам один вызов просто в 2 столбца, чтобы не считать:

ts1:                                                    tst2:
000E1918  mov         eax,dword ptr [v1]                000E19C8  mov         eax,dword ptr [v1]
000E191B  push        eax                               000E19CB  push        eax  
000E191C  call        a (0E137Ah)                       000E19CC  call        a (0E137Ah)  
000E1921  add         esp,4                             000E19D1  add         esp,4  
000E1924  movzx       ecx,al                            000E19D4  movzx       ecx,al  
000E1927  test        ecx,ecx                           000E19D7  test        ecx,ecx  
000E1929  je          tst1+3Fh (0E192Fh)                000E19D9  je          tst2+6Dh (0E1A0Dh)  
000E192B  mov         al,1                              000E19DB  mov         edx,dword ptr [v2]  
000E192D  jmp         tst1+6Fh (0E195Fh)                000E19DE  push        edx 


как видно, тут и команды почти друг друга повторяют, понятное дело, что в первом тесте нужно добавить еще несколько return

с 99% уверенностью, считаю, что на уровне процессора эти коды будут выполняться с одинаковой скоростью до такта - в процессоре еще оптимизация, распараллеливание и хз что еще на уровне микрокоманд работает