Interesante visión de la OLP - página 8

 
fxsaber:

Escribo así porque me gusta. Dicho esto, se pone muy mal cuando se depura.


Incluso en esta expresión.

es difícil saber quién devolvió qué. En los más complejos (lo practico todo el tiempo) es realmente difícil.

Si quieres usar 2-3... supongamos 5 resultados de la ejecución de funciones unidas por operaciones lógicas (u operador ternario condicional) - lo he visto en githab o en algún otro lugar, este código puede ser manejado

Pero si tienes una docena de estas "golosinas"... imho, no es práctico

 
Maxim Kuznetsov:

No soy un desarrollador de mql, por supuesto,

pero en C switch genera una búsqueda binaria bastante eficiente y no provoca una paginación de páginas o un volcado de caché innecesarios. Así que sí, a menudo es mejor que el direccionamiento indirecto a través de arrays y estructuras.

los desarrolladores escribieron en alguna parte y aquí información similar

sólo encontró esto:

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Este es el artículo que hemos encontrado en MQL5.

Slava, 2011.04.14 09:59

No, lamentablemente no lo hará. Para los tipos de cadena sólo si ... si no, si ... si no

El uso de tipos enteros en switch acelera el código del analizador varias veces más que si


 
Igor Makanu:

Pero si se trata de una docena... En mi opinión, no es práctico.

Pequeño monstruo.

  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__
           );
  }

Lasoperaciones lógicas permiten escribir de forma sucinta cuando se utilizan diferentes configuraciones mediante macros. Pero es un horror, por supuesto.

 
fxsaber:

Lasoperaciones lógicas permiten una escritura concisa cuando se utilizan varios ajustes mediante macros. Pero es un horror, por supuesto.

Tu ejemplo de "el fin justifica los medios"

mi pregunta era sobre un estilo muy diferente e incomprensible

 
fxsaber:

El pequeño monstruo.

A caballo regalado no se le mira el diente. Pero aquí hay un par de ejemplos más del código de otras personas, que me dieron unas docenas de minutos inolvidables de depuración. Quizás alguien reconozca su propio código.

      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));

No sé si fue fácil escribirlo así pero es irreal depurarlo, más aún leerlo. Y no veo ninguna razón objetiva para escribirlo así.

 
traveller00:

Y no veo ninguna razón objetiva para escribirlo así.

Son subjetivos, por supuesto. No me gustan las variables innecesarias ni las devoluciones múltiples. Por alguna razón, creo que la EX5 será más corta y se ejecutará más rápido sin ellos.

 
fxsaber:

Son subjetivos, por supuesto. No me gustan las variables innecesarias ni las devoluciones múltiples. Por alguna razón creo que la EX5 será más corta y rápida sin ellos.

Por cierto, esta confianza en que el código será más corto y rápido no está justificada.

aquí está

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

y esto

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

Estoy seguro de que será lo mismo en cuanto a velocidad (y quizás en cuanto al tamaño del código y la memoria utilizada).

Es que la segunda variante es más rápida de escribir y todo el mundo la escribe y luego, cuando es necesario añadir/complicar algo, dejan la segunda variante pero hinchada a una difícil de leer.

Deberá realizar periódicamente una refactorización en este sentido y no tendrá problemas.

 
Aleksey Mavrin:

Realice refacciones periódicas en este sentido y no habrá ningún problema.

Sólo para los que tienen mucho tiempo libre o están objetivamente tan presionados que no hay lugar para ir sin él.

Cuando hay mucho retorno, el código será 100% diferente.
 
fxsaber:

Sólo para los que tienen mucho tiempo libre o están objetivamente tan presionados que no hay lugar para ir sin él.

ZS Cuando hay mucho retorno, el código será 100% diferente.

Lo comprendo, pero en parte estoy de acuerdo, sólo que creo que todo el mundo ha experimentado tiempos relativamente largos en la corrección de errores, que se encontrarían más rápido si el código estuviera "perfectamente preparado" para la depuración.

No está claro qué consume más tiempo, si escribir código "utilizable" o depurar y encontrar errores, siempre es diferente, supongo.

 
fxsaber:

Cuando hay mucho retorno, el código será 100% diferente.

C++ VS2019 bajo el depurador

código fuente:

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);
}

depurador asm

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


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



reducido por comandos una llamada sólo en 2 columnas para no contar:

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


como puedes ver aquí y los comandos casi se repiten, está claro que en la primera prueba hay que añadir algún retorno más

con un 99% de confianza, creo que a nivel de procesador estos códigos funcionarán a la misma velocidad hasta un reloj - en la optimización del procesador, el paralelismo y quién sabe qué más funciona a nivel de microcomandos