Un point de vue intéressant sur l'OLP - page 8

 
fxsaber:

J'écris de cette façon parce que j'aime ça. Cela dit, cela devient vraiment mauvais lors du débogage.


Même dans cette expression.

c'est difficile de savoir qui a rendu quoi. Dans les plus complexes (je le pratique tout le temps), c'est vraiment difficile.

Si vous voulez utiliser 2-3... supposons que 5 résultats d'exécution de fonctions unis par des opérations logiques (ou opérateur ternaire conditionnel) - je l'ai vu sur githab ou ailleurs, ce code peut être traité

Mais si vous avez une douzaine de ces "goodies"... imho, ce n'est pas pratique

 
Maxim Kuznetsov:

Je ne suis pas un développeur mql, bien sûr,

mais en C, le commutateur génère une recherche binaire assez efficace et ne provoque pas de pagination inutile ni de vidage du cache. Donc oui, c'est souvent mieux que l'adressage indirect via les tableaux et les structures.

les développeurs ont écrit quelque part et ici des informations similaires

n'a trouvé que ça :

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

Voici l'article que nous avons trouvé dans MQL5.

Slava, 2011.04.14 09:59

Non, malheureusement, ce ne sera pas le cas. Pour les types de chaînes de caractères, seulement si ... sinon si ... sinon

L'utilisation de types entiers dans le switch accélère le code de l'analyseur plusieurs fois plus que si


 
Igor Makanu:

Mais si c'est une douzaine ou plus... imho, ce n'est pas pratique.

Petit monstre.

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

Lesopérations logiques vous permettent d'écrire succinctement lorsque vous utilisez différents paramètres via des macros. Mais c'est une horreur, bien sûr.

 
fxsaber:

Lesopérations logiques permettent une écriture concise lors de l'utilisation de divers paramètres via des macros. Mais c'est une horreur, bien sûr.

Votre exemple de "la fin justifie les moyens".

ma question portait sur un style très différent et incompréhensible

 
fxsaber:

Le petit monstre.

On ne peut pas regarder un cheval donné dans la bouche. Mais voici quelques autres exemples de code d'autres personnes, qui m'ont donné quelques dizaines de minutes inoubliables de débogage. Peut-être que quelqu'un reconnaîtra son propre code.

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

Je ne sais pas si c'était facile de l'écrire comme ça mais c'est irréel de le déboguer, d'autant plus de le lire. Et je ne vois pas de raisons objectives pour l'écrire de cette façon.

 
traveller00:

Et je ne vois pas de raisons objectives pour l'écrire de cette façon.

Elles sont subjectives, bien sûr. Je n'aime pas les variables inutiles et les retours multiples. Pour une raison quelconque, je crois que le EX5 sera plus court et exécuté plus rapidement sans eux.

 
fxsaber:

Elles sont subjectives, bien sûr. Je n'aime pas les variables inutiles et les retours multiples. Pour une raison quelconque, je crois que l'EX5 sera plus court et plus rapide sans eux.

D'ailleurs, cette confiance dans le fait que le code sera plus court et plus rapide n'est pas justifiée.

c'est ici

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

et ceci

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

Je suis sûr que la vitesse sera la même (et peut-être la taille du code et de la mémoire utilisée).

C'est juste que la seconde variante est plus rapide à écrire et que tout le monde l'écrit, puis, lorsqu'il est nécessaire d'ajouter/compliquer quelque chose, ils laissent la seconde variante mais gonflée en une variante difficile à lire.

Vous devriez périodiquement effectuer un remaniement à cet égard et vous n'aurez pas de problèmes.

 
Aleksey Mavrin:

Effectuez périodiquement des remaniements à cet égard et il n'y aura aucun problème.

Seulement pour ceux qui ont beaucoup de temps libre ou qui sont objectivement si pressés qu'il n'y a nulle part où aller sans cela.

Lorsqu'il y a beaucoup de retours, le code sera différent à 100%.
 
fxsaber:

Seulement pour ceux qui ont beaucoup de temps libre ou qui sont objectivement si pressés qu'il n'y a nulle part où aller sans cela.

ZS Quand il y a beaucoup de retours, le code sera différent à 100%.

Je comprends, je suis en partie d'accord, je pense juste que tout le monde a fait l'expérience de temps de correction de bogues relativement longs, qui seraient trouvés plus rapidement si le code était "parfaitement prêt" pour le débogage.

On ne sait pas ce qui prend le plus de temps - écrire du code "utilisable" ou déboguer et trouver des bugs, c'est toujours différent je suppose.

 
fxsaber:

Quand il y a beaucoup de retours, le code sera 100% différent.

C++ VS2019 sous débogueur

code source :

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

débogueur 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]  
}



réduit par les commandes un appel juste dans 2 colonnes à ne pas compter :

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 


comme vous pouvez le voir ici et les commandes se répètent presque l'une l'autre, il est clair que dans le premier test vous devez ajouter un peu plus de retour

avec 99 % de confiance, je pense qu'au niveau du processeur, ces codes fonctionneront à la même vitesse jusqu'à une horloge - dans le processeur, l'optimisation, la mise en parallèle et qui sait quoi d'autre fonctionnent au niveau des micro-commandes.