domanda per gli esperti di #define - pagina 5

 
Alexandr Andreev:

Dammi il codice completo del tuo test

Ecco qui, ma non vedo il motivo per discutere di nuovo di rand(), in alternativa sostituitelo con qualche variabile inc++

#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count&&!_StopFlag;_i++){EX;} \
                                              printf("%s: loops = %llu seconds=%.4f",msg,count,(double)(GetTickCount()-mss)/1000000.0);}



//+------------------------------------------------------------------+
void OnStart()
{
   int arr1[], arr2[], arr3[];
   int cnt1 = ArrayResize(arr1, 100);
   int cnt2 = ArrayResize(arr2, 200);
   int cnt3 = ArrayResize(arr3, 300);
   ulong sum = 0;

   SpeedTest(3,"ArraySize",
      for(int i = 0; i < ArraySize(arr1); i++)
      {
         for(int j = 0; j < ArraySize(arr2); j++)
         {
            for(int k = 0; k < ArraySize(arr3); k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )
   
   SpeedTest(3,"cnt",
      for(int i = 0; i < cnt1; i++)
      {
         for(int j = 0; j < cnt2; j++)
         {
            for(int k = 0; k < cnt3; k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )

}


Sì... Ho un errore nel mio codice, voglio emettere il tempo in secondi, ma ottengo 10 volte di più, l'ho diviso correttamente per 1 000 000, chi può dirmi qual è la ragione?

 
Igor Makanu:

Ecco qui, ma non vedo il senso di discutere ancora di rand(), in alternativa sostituitelo con qualche variabile inc++


Sì... Qualche tipo di errore nel mio codice, voglio emettere il tempo in secondi, ma ottengo 10 volte di più, l'ho diviso correttamente per 1 000 000, chi può dirmi qual è la ragione?

BOMBA.

Ecco il tuo codice che dimostra che è il contrario.

//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count&&!_StopFlag;_i++){EX;} \
                                              printf("%s: loops = %llu seconds=%.4f",msg,count,(double)(GetTickCount()-mss)/1000000.0);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void OnStart()
{
   int arr1[], arr2[], arr3[];
   int cnt1 = ArrayResize(arr1, 100);
   int cnt2 = ArrayResize(arr2, 200);
   int cnt3 = ArrayResize(arr3, 300);
   ulong sum = 0;

   
   SpeedTest(3,"cnt",
      for(int i = 0; i < cnt1; i++)
      {
         for(int j = 0; j < cnt2; j++)
         {
            for(int k = 0; k < cnt3; k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )

   SpeedTest(3,"ArraySize",
      for(int i = 0; i < ArraySize(arr1); i++)
      {
         for(int j = 0; j < ArraySize(arr2); j++)
         {
            for(int k = 0; k < ArraySize(arr3); k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )
}
 
Alexandr Andreev:

BOMBA

Ecco il tuo codice che dimostra il contrario.

Ho solo scambiato gli assegni.

 
Alexandr Andreev:

Ho appena scambiato gli assegni

2020.11.02 21:01:38.590 22222 (USDCHF,H1) cnt: loops = 1000 seconds=821.7159

2020.11.02 21:01:52.353 22222 (USDCHF,H1) ArraySize: loops = 1000 seconds=807.9415


Da questo risulta cheArraySize è più veloce che usare una variabile =)) qualcosa è sbagliato nel test
 
Roman:

Quale test? ))
Tu stesso hai mostrato entrambe le varianti della condizione del ciclo.
Anche Igor ha dato il codice qui sopra.
Basta misurare le prestazioni del ciclo con dimensioni variabili e con ArraySize() nella condizione del ciclo.

Dimostrami che mi sbaglio)

perché nel mio test sono gli stessi

 
Alexandr Andreev:

Ho solo scambiato gli assegni.

Sì, devi farlo.

Questa volta sono stato troppo pigro.

Avvolgendo i test in un ciclo esterno, l'ho ottenuto così:

2020.11.02 22:06:43.557 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=117.4626

2020.11.02 22:06:58.328 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=102.7337

2020.11.02 22:07:13.075 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=87.9782

2020.11.02 22:07:27.850 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=73.2461

2020.11.02 22:07:42.598 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=58.4859

2020.11.02 22:07:57.380 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=43.7522

2020.11.02 22:08:12.891 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=28.9861

2020.11.02 22:08:28.874 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=13.4910

 
Igor Makanu:

Sì, deve essere fatto.

Questa volta sono stato troppo pigro.

Avvolgendo i test in un ciclo esterno, ho ottenuto questo

2020.11.02 22:06:43.557 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=117.4626

2020.11.02 22:06:58.328 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=102.7337

2020.11.02 22:07:13.075 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=87.9782

2020.11.02 22:07:27.850 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=73.2461

2020.11.02 22:07:42.598 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=58.4859

2020.11.02 22:07:57.380 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=43.7522

2020.11.02 22:08:12.891 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=28.9861

2020.11.02 22:08:28.874 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=13.4910

Ora scambiateli nel ciclo e lasciatevi stupire

 
Alexandr Andreev:

Ora scambiateli nel ciclo e sarete sorpresi

So che il compilatore può ottimizzare il codice al volo

ma, imho, nei loop annidati, non dovreste ancora chiamare ArraySize() inutilmente.

for(int i = ArraySize(arr)-1; i >=0 ; i--)

Certo, a volte può essere scomodo, quindi faccio il ciclo tramite una variabile temporanea - la tua versione № 2

imho, è affidabile e si capisce cosa succederà

 

Beh, non posso dire nulla contro IMHO.

Su replay molto grandi, le mie vittorie sono diventate casuali per il primo e il secondo metodo... Molto probabilmente è diventato dipendente dalla cache corrente della CPU e dal carico complessivo.

La mia domanda non riguardava il ciclo, ma come si svolgeva la funzione. Solo come esempio era ArraySize

Il risultato;

for (int i=0; i<ArraySIze(mas); i++) == for (int i=0; i<size; i++)


Ma se aggiungiamo l'inizializzazione della variabile dimensione alla seconda parte, allora il primo metodo prende il comando per il tempo di inizializzare questa variabile e di equipararla al valore.

 

Se si cambia la dimensione degli array nel corpo del ciclo, l'ottimizzazione al volo non funziona

quindi cambiate il codice:

for(int loop=0; loop <5;loop++)
   {
   int cnt1 = ArrayResize(arr1, 100+loop);
   int cnt2 = ArrayResize(arr2, 200+loop);
   int cnt3 = ArrayResize(arr3, 300+loop);
   
   SpeedTest(3,"cnt",
.....

Alexandr Andreev:

allora il primo metodo ha la precedenza, per il tempo di inizializzare questa variabile e di equipararla a un valore, si nota solo ad alte ripetizioni

non funziona

l'ottimizzazione runtime sarà in testa

non puoi testare mashidas così semplici senza il profiler, in generale, puoi scrivere in un ciclo, o puoi testare nel tester, la velocità è importante per questo

Motivazione: