Dichiarare le variabili dietro il ciclo o dentro il ciclo?

 
   string st = "";
   for (int i = 0; i < 1000; i++)
   {
      st = i;
      ...
   }

o

   for (int i = 0; i < 1000; i++)
   {
      string st = i;
      ...
   }

C'è una differenza, date tutte le ottimizzazioni del compilatore mql5?

 
pivalexander:

o

C'è una differenza, date tutte le ottimizzazioni del compilatore mql5?

Non c'è differenza nella compilazione, quindi sentitevi liberi di usare la seconda opzione.
 

Personalmente, preferisco il primo.

Non si sa mai. Il compilatore potrebbe essere abbastanza intelligente da non allocare la memoria ogni volta, ma nel primo caso lo specifico esplicitamente, ma nel secondo caso è un risultato implicito del compilatore, perché la logica del linguaggio è quella di creare una variabile all'interno di un blocco e rimuoverla all'uscita dal blocco.

E equiparare int a stringa senza trasformazione è una cattiva pratica.

 
pivalexander:

C'è una differenza, date tutte le ottimizzazioni del compilatore mql5?

Non ascoltate che non c'è differenza. Usate solo la prima opzione, c'è una differenza. Non ho studiato il disassm di mcl però.

 
Georgiy Merts:

Personalmente, preferisco il primo.

Non si sa mai. Il compilatore può essere abbastanza intelligente da non allocare la memoria ogni volta, ma nel primo caso lo specifico esplicitamente, ma nel secondo caso è un risultato implicito del compilatore, perché la logica del linguaggio è di creare una variabile all'interno di un blocco, e quando si esce dal blocco, deve essere cancellata.

E equiparare int a stringa senza convertirlo è una cattiva pratica.

George ha ragione, non è garantito.

E otteniamo una deformazione della conversione implicita da 'numero' a 'stringa'.


Ed è esattamente così che ci liberiamo dell'indeterminazione e della deformazione.

for (int i = 0; i < 1000; i++)
   {
      static string st = IntegerToString(i);
      ...
   }
 
Georgiy Merts:

Personalmente, preferisco il primo.

Non si sa mai. Il compilatore può essere abbastanza intelligente da non allocare memoria ogni volta, ma nel primo caso lo specifico esplicitamente, mentre nel secondo caso è un risultato implicito del lavoro del compilatore

Stai scherzando? È una situazione così banale per il compilatore che non c'è nulla di cui parlare. Potresti essere così paranoico al riguardo che hai solo bisogno di codificare in assembler. Anche se anche questo diventa già insensato al giorno d'oggi. Dovrai provare duramente a battere l'ottimizzazione dei compilatori moderni.

p.s. Forse ero un po' eccitato per la banalità nel caso del buffer di stringhe. Ma è garantito il salvataggio in MQL, non solo all'interno del ciclo ma anche tra le chiamate di funzione. Questo argomento è stato discusso qui più di una volta
 

Non ascoltateli, vi racconteranno un sacco di cose qui ))

// c++
#include <iostream>
#include <string>
using namespace std;

void* operator new(size_t sz) {
    void *ptr = std::malloc(sz);
    if (ptr)
        return ptr;
    else
        throw std::bad_alloc{};
}


int main() {
        for (uint i = 0;  i < 3;  ++ i) {
                string s;
                char buf[10];
                sprintf(buf, "%u", i);
                s = "sfjhidfsrtea111";
                s += buf;
                cout << s << '\n';
        }
}

Compilo gcc -O3, lo eseguo sotto il debugger, imposto il breakpoint sull'operatore nuovo, ottengo tre chiamate. Lo stesso vale per il clang.

Nota: se la stringa viene tolta dal ciclo, ricevo una chiamata.

 
Alexey Navoykov:

Stai scherzando? È una situazione così banale per un compilatore che non c'è nulla di cui parlare. Se sei così paranoico, potresti scrivere il codice puramente in assembler. Ma anche questo sta diventando insensato al giorno d'oggi. Dovrai sforzarti di battere l'ottimizzazione dei compilatori moderni.

p.s. Forse ero un po' eccitato per la banalità nel caso del buffer di stringhe. Ma è garantito il salvataggio in MQL, non solo all'interno del ciclo ma anche tra le chiamate di funzione. Questo argomento è stato discusso qui più di una volta

No, non lo sono.

Certamente, un compilatore normale in questo caso dovrebbe portare all'esterno una dichiarazione di variabile all'interno di un ciclo.

Penso solo che dovresti sempre fidarti del compilatore e fidarti di te stesso. È uno standard del compilatore che una variabile locale viene creata quando viene dichiarata e viene rimossa quando si esce dal blocco in cui è stata dichiarata. Quindi dovreste concentrarvi su questo principio in primo luogo e non aspettare che il compilatore migliori il vostro codice per voi.

Non si tratta di efficienza (i compilatori moderni danno davvero un codice di altissima qualità) ma dello schema di pensiero del programmatore. Quando guardo il codice sorgente di Kodobase, spesso mi chiedo quanti piccoli e semplici ma potenzialmente pericolosi difetti contengono. In questo caso non è ancora molto critico, il massimo che può succedere è che il programma lavorerà un po' più lentamente. Gli errori reali potrebbero essere molto più complicati.

 
Vict:

Non ascoltateli, vi racconteranno un sacco di cose qui ))

Compilo gcc -O3, lo eseguo sotto il debugger, imposto il breakpoint sull'operatore nuovo, ottengo tre chiamate. Lo stesso vale per il clang.

Quindi, se la stringa viene tolta dal ciclo, ottengo una chiamata.

Non avrebbe potuto fare altrimenti perché tu stesso hai interferito con l'ottimizzazione tramite i punti di rottura. L'essenza dell'ottimizzazione è che non dovrebbe cambiare la logica dell'algoritmo. Ecco perché non può essere rilevato esplicitamente. Se c'è un breakpoint lì, ovviamente il compilatore non ha il diritto di tagliare questo codice. Ti aspettavi che il compilatore potesse saltare il breakpoint? )

È possibile rilevare l'ottimizzazione solo compilando il codice o misurando le sue prestazioni, quindi questa è la prima cosa da fare. E calmati )

 
Aspettando le misure)
 
Alexey Navoykov:

Non potrebbe fare altrimenti perché tu stesso hai interferito con l'ottimizzazione con i punti di rottura. Il punto dell'ottimizzazione è che non deve cambiare la logica dell'algoritmo. Ecco perché non può essere rilevato esplicitamente. Se c'è un breakpoint lì, il compilatore naturalmente non ha il diritto di tagliare questo codice. Ti aspettavi che il compilatore potesse saltare il breakpoint? )

È possibile rilevare l'ottimizzazione solo compilando il codice o misurando le sue prestazioni, quindi questa è la prima cosa da fare. E calmati )

Amico, questo è solo selvaggiamente stupido, cosa c'è da commentare, un completo fraintendimento di come funziona il debugger.

Circa la velocità - gestore di memoria non è così stupido, e non il fatto che chiederà il sistema operativo, può sovrautilizzare prima assegnato. In generale, usatelo come volete, dipende da voi. Ma non bisogna convincere gli altri di questo, almeno finché non si forniscono prove concrete, dove sono?

Motivazione: