Interessante presa di posizione sull'OLP - pagina 8

 
fxsaber:

Scrivo così perché mi piace. Detto questo, diventa davvero brutto quando si fa il debug.


Anche in questa espressione.

è difficile capire chi ha restituito cosa. In quelli più complessi (lo pratico sempre) è davvero difficile.

Se vuoi usare 2-3... Supponiamo 5 risultati dell'esecuzione di funzioni unite da operazioni logiche (o operatore condizionale ternario) - l'ho visto su githab o da qualche altra parte, questo codice può essere gestito

Ma se hai una dozzina di queste "chicche"... imho, non è pratico

 
Maxim Kuznetsov:

Non sono uno sviluppatore di mql, ovviamente,

ma in C switch genera una ricerca binaria abbastanza efficiente e non causa paginazione inutile o scarico della cache. Quindi sì, spesso è meglio dell'indirizzamento indiretto tramite array e strutture.

gli sviluppatori hanno scritto da qualche parte e qui informazioni simili

ha trovato solo questo:

Forum sul trading, sistemi di trading automatico e test di strategia

Questo è l'articolo che abbiamo trovato in MQL5.

Slava, 2011.04.14 09:59

No, purtroppo no. Per i tipi di stringa solo se ... altrimenti se ... else

L'uso di tipi interi in switch velocizza il codice dell'analizzatore diverse volte di più che se


 
Igor Makanu:

Ma se sono una decina... imho, non è pratico.

Piccolo mostro.

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

Leoperazioni logiche permettono di scrivere in modo succinto quando si usano diverse impostazioni tramite macro. Ma è un orrore, ovviamente.

 
fxsaber:

Leoperazioni logiche permettono una scrittura concisa quando si utilizzano varie impostazioni tramite macro. Ma è un orrore, ovviamente.

Il tuo esempio di "il fine giustifica i mezzi"

lamia domanda riguardava uno stile molto diverso e incomprensibile

 
fxsaber:

Il piccolo mostro.

A caval donato non si guarda in bocca. Ma ecco un altro paio di esempi di codice di altre persone, che mi hanno dato alcune indimenticabili decine di minuti di debugging. Forse qualcuno riconoscerà il proprio codice.

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

Non so se è stato facile scriverlo così, ma è irreale debuggarlo, tanto più leggerlo. E non vedo alcuna ragione oggettiva per scriverlo in quel modo.

 
traveller00:

E non vedo alcuna ragione oggettiva per scriverlo in quel modo.

Sono soggettivi, ovviamente. Non mi piacciono le variabili inutili e i ritorni multipli. Per qualche ragione, credo che EX5 sarà più breve ed eseguito più velocemente senza di loro.

 
fxsaber:

Sono soggettivi, ovviamente. Non mi piacciono le variabili inutili e i ritorni multipli. Per qualche ragione credo che EX5 sarà più breve e più veloce senza di loro.

A proposito, questa fiducia che il codice sarà più breve e più veloce non è giustificata.

ecco qui

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

e questo

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

Sono sicuro che sarà lo stesso in velocità (e forse in dimensione del codice e della memoria utilizzata).

È solo che la seconda variante è più veloce da scrivere e tutti la scrivono e poi, quando è necessario aggiungere/complicare qualcosa, lasciano la seconda variante ma gonfiata a una difficile da leggere.

Dovreste eseguire periodicamente il refactoring in questo senso e non avrete problemi.

 
Aleksey Mavrin:

Fate periodicamente il refactoring in questo senso e non ci saranno problemi.

Solo per coloro che hanno molto tempo libero o sono oggettivamente così pressati che non c'è un posto dove andare senza.

Quando c'è molto ritorno, il codice sarà al 100% diverso.
 
fxsaber:

Solo per coloro che hanno molto tempo libero o sono oggettivamente così pressati che non c'è un posto dove andare senza.

ZS Quando c'è molto ritorno, il codice sarà al 100% diverso.

Capisco, ma in parte sono d'accordo, penso solo che tutti abbiano sperimentato tempi relativamente lunghi per la risoluzione dei bug, che sarebbero trovati più velocemente se il codice fosse "perfettamente pronto" per il debug.

Non è chiaro cosa mangia più tempo - scrivere più a lungo il codice "utilizzabile" o fare il debug e trovare i bug, è sempre diverso credo.

 
fxsaber:

Quando c'è molto ritorno, il codice sarà diverso al 100%.

C++ VS2019 sotto debugger

codice sorgente:

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

debugger 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]  
}



ridotto da comandi una chiamata solo in 2 colonne per non contare:

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 


come potete vedere qui e i comandi si ripetono quasi l'un l'altro, è chiaro che nel primo test è necessario aggiungere qualche altro ritorno

con il 99% di fiducia, penso che a livello di processore questi codici gireranno alla stessa velocità fino a un clock - nell'ottimizzazione del processore, il parallelismo e chissà cos'altro funziona a livello di microcomandi

Motivazione: