Dichiarare le variabili dietro il ciclo o dentro il ciclo? - pagina 5

 
pivalexander:

Preferisco dividere il codice in blocchi logici e dichiarare le variabili necessarie in essi, piuttosto che creare un mucchio di variabili all'inizio di una funzione, la maggior parte delle quali sono necessarie solo in un blocco, da qualche parte in basso

Per le variabili necessarie in un solo posto - sì, ha senso dichiararle prima del blocco stesso, specialmente quando il blocco è piccolo. Ma, se il blocco è abbastanza grande e le variabili sono necessarie altrove - preferirei dichiararle all'inizio della funzione. Qui però bisogna usare il buon senso.

 
pivalexander:

Il risultato dell'esecuzione con un corpo del ciclo vuoto è molto diverso, molto più veloce

Test1, время выполнения: 0.548275 сек.
Test2, Время выполнения: 0.313978 сек.

Cosa si misura in microsecondi? .... Sei sicuro di avere un test realistico?

;)

Ecco un altro test come questo:

#define  N 8

#define    test(M,S,EX,res) {                             \
uint mss=GetTickCount();                                 \
ulong nn=(ulong)pow(10,M);                               \
for(ulong tst=0;tst<nn && !_StopFlag;tst++) \
{ EX;  res }                                             \
printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   string result;
   string s1;  test(N,"1. s1=",s1=(string)tst, result = s1;);
   string s2;  test(N,"2. s2=",s2=(string)tst, result = s2;);
   string s3;  test(N,"3. s3=",s3=(string)tst, result = s3;);
   string s4;  test(N,"4. s4=",s4=(string)tst, result = s4;);
   string s5;  test(N,"5. s5=",s5=(string)tst, result = s5;);

   test(N,"1. q=",string q=(string)tst, result = q;);
   test(N,"2. w=",string w=(string)tst, result = w;);
   test(N,"3. e=",string e=(string)tst, result = e;);
   test(N,"4. r=",string r=(string)tst, result = r;);
   test(N,"5. t=",string t=(string)tst, result = t;);
  }

2019.08.18 12:14:20.765 SpeedTest (EURUSD,H1) 1. s1=: loops=100000000 ms=8156

2019.08.18 12:14:29.127 SpeedTest (EURUSD,H1) 2. s2=: loops=100000000 ms=8359

2019.08.18 12:14:37.353 SpeedTest (EURUSD,H1) 3. s3=: loops=100000000 ms=8235

2019.08.18 12:14:45.464 SpeedTest (EURUSD,H1) 4. s4=: loops=100000000 ms=8109

2019.08.18 12:14:53.557 SpeedTest (EURUSD,H1) 5. s5=: loops=100000000 ms=8094

2019.08.18 12:15:01.446 SpeedTest (EURUSD,H1) 1. q=: loops=100000000 ms=7890

2019.08.18 12:15:09.159 SpeedTest (EURUSD,H1) 2. w=: loops=100000000 ms=7703

2019.08.18 12:15:16.903 SpeedTest (EURUSD,H1) 3. e=: loops=100000000 ms=7750

2019.08.18 12:15:24.716 SpeedTest (EURUSD,H1) 4. r=: loops=100000000 ms=7813

2019.08.18 12:15:32.661 SpeedTest (EURUSD,H1) 5. t=: loops=100000000 ms=7937

 
Igor Makanu:

Cosa si misura in microsecondi? .... Sei sicuro che il tuo test corrisponda alla realtà?

   ulong  time_finish = GetMicrosecondCount();
   ulong  res = time_finish - time_start;

È così che lo misuro.

 
pivalexander:

Io misuro in questo modo.

Lo capisco, ma bisogna misurare almeno qualche secondo

Windows non è un sistema in tempo reale, vero? E anche i compiti in background richiedono risorse da Windows, quindi i tuoi test sono a livello di imprecisione del timer di sistema e dei processi in background

imho, un test di almeno 5 secondi è almeno qualche informazione affidabile

 
Igor Makanu:

Lo capisco, ma bisogna misurare almeno qualche secondo

Windows non è un sistema in tempo reale, vero? E anche i compiti in background richiedono risorse da Windows, quindi i tuoi test sono a livello di imprecisione del timer di sistema e dei processi in background

imho, un test di almeno 5 secondi è almeno qualche informazione credibile

Ho misurato diversi secondi ciascuno, il risultato è lo stesso, perché aspettare così tanto per postare il risultato qui

 

In generale ho deciso di fare un test, ma corretto al 100%, in modo che nulla fosse tagliato.

void OnStart()
{
  int count= (int)10 e6;

  { 
    uint t= GetTickCount();
    int sum=0;
        
    for (int i=0; i<count; i++)
    {
       string st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test1, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
  
  {
    uint t = GetTickCount();
    int sum=0;
    string st = "";
    for (int i=0; i<count; i++)
    {
       st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test2, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
}

In modalità non ottimizzata la seconda variante risulta essere più veloce, mentre in modalità ottimizzata è viceversa. La seconda variante, nel frattempo, diventa in qualche modo più lenta di quanto fosse prima dell'ottimizzazione)

 
pivalexander:

Ha fatto misurazioni per pochi secondi alla volta, il risultato è lo stesso, perché aspettare a lungo per postare il risultato qui

e più volte lo stesso test deve essere eseguito, perché c'è un'alta probabilità di operazioni di caching nel prossimo test per ottenere, che può venire fuori che 2 test identici con piccole differenze saranno eseguiti in modo diverso - non vedi la differenza dello stesso test?

Dipende da voi, come ho scritto sopra, non mi fido di nessuno, nemmeno di Windows, del processore e di me stesso ;)


Alexey Navoykov:

In generale ho deciso di fare un test, ma corretto al 100%, che nulla è stato tagliato fuori.

Mentre in modalità non ottimizzata la seconda variante è effettivamente più veloce, in modalità ottimizzata è viceversa. E il secondo modo, per qualche motivo, diventa più lento di prima dell'ottimizzazione)

Non è un fatto, non c'è srand() , ti ho detto che rand() è molto figo ottimizzato dal compilatore ;)

E copiate il testo dello script almeno 2 volte - in modo da poter vedere ciò che il compilatore ha strappato ;)

 
pivalexander:

Cosa c'entrano la memoria e il processore? Si tratta di ottimizzazione, sei un teorico dei libri)

Se andate oltre le parentesi nel vostro ragionamento e capite come funziona un compilatore e come funziona la sua ottimizzazione, vedrete che lo scopo di qualsiasi compilatore è quello di ridurre il numero di cicli di clock di esecuzione del codice e di ridurre il più possibile gli accessi non sequenziali alla memoria. Di conseguenza, il risultato dell'ottimizzazione di qualsiasi compilatore, se esiste, vi sarà noto in anticipo senza alcun test stupido. È come usare i test per capire che 2 + 2 = 4...

E riguardo al teorico del libro... Questo teorico scrive dall'87, iniziando con EC1020 e ZX Spectrum, ha scritto più di un compilatore e ha assunto più di 600 programmatori nella sua azienda...

 
Aleksandr Matveev:

Se andate oltre le parentesi nel vostro ragionamento e capite come funziona il compilatore e come funziona la sua ottimizzazione, vedrete che lo scopo di qualsiasi compilatore è quello di ridurre il numero di cicli di clock di esecuzione del codice e ridurre il più possibile gli accessi non sequenziali alla memoria e, di conseguenza, il risultato di qualsiasi ottimizzazione del compilatore, se c'è, vi sarà noto in anticipo senza alcun test stupido. È come usare i test per capire che 2 + 2 = 4...

E riguardo al teorico del libro... Questo teorico lavora dall'87 quando ha iniziato a lavorare con EU1020 e ZX Spectrum, ha scritto diversi compilatori per conto suo e ha invitato più di 600 programmatori nella sua azienda...

Vi date da fare con i libri, lodando voi stessi, ma non hanno detto nulla sull'essenza della questione, solo ballando intorno alla teoria... Se leggete questo lo capirete... Memoria e CPU, CPU e memoria, più sull'alimentazione, si usa anche lì...

 
Sapevate che una stringa può avere un piccolo buffer interno e per le stringhe piccole, i dati possono andarci per intero? Perciò, per accelerare la maggior parte dei casi banali. Giocando con la cattura di malloc(), ho notato che se la stringa è più corta di circa 15 caratteri, malloc non si agita affatto. Come sarebbero i vostri test ...