domanda per gli esperti di #define - pagina 7

 
Alexandr Andreev:

Non avete mischiato nulla nel vostro codice, chi cambierà il valore per voi?

come nella prima versione.

Sì, mi è sfuggito questo punto. Ho corretto il mio post.

 
Valeriy Yastremskiy:

Lì c'è un risultato casuale. La compilazione svolge l'accesso a una cella di memoria con un valore di dimensione dell'array, e la dimensione dell'array sarà ottenuta e posta nella cella di memoria in anticipo, quando l'array è formato, anche se l'array è dinamico, e le celle con una dimensione di array e con un valore variabile avranno lo stesso tempo di accesso.

E a giudicare dalla frase che fanno i compilatori nel corso di informatica di 3-4 anni... in generale, spero che un livello di personale sufficientemente adeguato non mi renda molto nervoso nell'ambiente MCL)

Credetemi lo studente medio di solito FIVT è solo zero con plus), poiché non c'è esperienza zero, e la conoscenza senza esperienza va rapidamente da nessuna parte (dimenticata), e i loro esempi sono molto strani, ci vorranno anni prima che lo studente capisca dove e come possono essere usati. Questo se lo si confronta con un programmatore esperto.

 
Alexandr Andreev:

Credetemi, lo studente medio FIVT è di solito uno zero più), perché c'è zero esperienza, e la conoscenza senza esperienza non va da nessuna parte (viene dimenticata), e i loro esempi sono molto strani, ci vorranno anni prima che lo studente capisca dove e come possono essere usati. Questo se lo si confronta con un programmatore esperto.

È comprensibile. Non capisco perché si debba insegnare a fare un compilatore. È come insegnare a creare la propria lingua. È chiaro che una lingua è una classe, ma non tutti gli uccelli possono volare a priori. Bene, come ho già detto sopra, Errori, Bug, Domande sono anche rilevanti per la questione dell'ottimizzazione della compilazione al volo.

 

L'argomento riguarda le definizioni, non i loop ))

Ma ancora non capisco, ha senso definire del codice, per esempio, delle funzioni definite dall'utente.
Nella speranza che il codice defunto venga eseguito più velocemente nel file eseguibile.
O è un malinteso? Perché la sostituzione è solo un'azione di precompilazione, e ha senso solo per accelerare la compilazione.

 
Roman:

L'argomento riguarda le definizioni, non i loop ))

Ma ancora non capisco, ha senso definire del codice, per esempio, delle funzioni definite dall'utente.
Nella speranza che il codice defunto venga eseguito più velocemente nel file eseguibile.
O è un malinteso? Perché la sostituzione è solo un'azione di precompilazione, ed è solo logica per accelerare la compilazione.

Vi ho appena mostrato un esempio in cui si usano 3 funzioni esterne... contro la sua forma dispiegata. Quindi non ci sarà alcuna accelerazione.

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

Domanda per gli esperti di #define

Alexandr Andreev, 2020.11.02 19:49

void OnStart()
  {
   int mas[];
   int size=1000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100;
   uint t1=GetTickCount();
   int t=0;
   int tr=0; 
   MathSrand(10);
   for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); Funk(i))
        { 
         FunkRand(r1); 
         Funk(r);// мы сюда написали вызов еще одной функции чтобы усложить ситуацию
        }
     }
   tr=r;
   uint t2=GetTickCount();
   for(ulong z=0; z<max; z++)
     {
     int v=size;
      for(ulong i=0; i<v; i++)
        { 
         r2+=rand();
         r--;
        }

     }

   uint t3=GetTickCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",t1," ",tr);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

500p domanda (senza controllo) che modo è più veloce. vedere quante funzioni esterne sono chiamate nel metodo superiore


Документация по MQL5: Основы языка / Функции / Описание внешних функций
Документация по MQL5: Основы языка / Функции / Описание внешних функций
  • www.mql5.com
Внешние функции, определенные в другом модуле, должны быть явно описаны. Описание включает в себя тип возвращаемого значения, имя функции и набор входных параметров с их типами. Отсутствие такого описания может привести к ошибкам при компиляции, компоновке или выполнении программы. При описании внешнего объекта используйте ключевое слово С...
 
Alexandr Andreev:

Vi ho dato un esempio in cui si usano 3 funzioni esterne... contro la sua forma dispiegata. Quindi non ci sarà alcuna accelerazione.


Capisco. Allora ciao a fxsaber. Un tipo a cui piace defundare tutto.


Alexandr Andreev:

Dimostrami che mi sbaglio)

perché nel mio test sono uguali per qualche motivo.

Come per ArraySize() e variabile. Ritornerò ancora su questa domanda.
Ecco cosa ho cambiato nel test. Il ciclo conta il numero di PI.
Nel primo esempio, la condizione del ciclo usa ArraySize().
Nel secondo esempio, viene utilizzata la variabile num_steps.
C'è una differenza.

Funzione ArraySize()

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<ArraySize(arr); i++)
    {
       x = (i + .5) * step;
       sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Tre prove della sceneggiatura.

2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  Total time to calculate PI was 4049.179 ms
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  Total time to calculate PI was 4183.364 ms
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  Total time to calculate PI was 4034.098 ms
        


Variabile num_steps.

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<num_steps; i++)
    {
        x = (i + .5) * step;
        sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Tre prove della sceneggiatura.

2020.11.03 00:08:09.269 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  Total time to calculate PI was 3955.325 ms
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  Total time to calculate PI was 3950.568 ms
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  Total time to calculate PI was 3927.110 ms
        
 
Roman:

Capisco. Allora ciao a fxsaber. Un fan di definire tutto in una riga.

Come per ArraySize() e la variabile. Tornerò comunque a questa domanda.
Ecco il test che ho modificato. Il ciclo conta il numero di PI.
Nel primo esempio, la condizione del ciclo usaArraySize().
Nel secondo esempio,
viene utilizzatala variabile num_steps.
C'è una differenza.

Funzione ArraySize()

Tre prove della sceneggiatura.


Variabile num_steps.

Tre prove della sceneggiatura.

Non c'è una differenza evidente in questi calcoli. Ho messo tutto questo in un codice e i risultati sono diversi, ce n'è uno in cui la prima variante vince

)) qualsiasi array in µl ha una variabile che è responsabile della dimensione corrente dell'array, quindi nella maggior parte dei linguaggi.

La funzione ArraySize dice al compilatore di restituire il valore di questa variabile, cioè sostituisce questa variabile invece di questa funzione. Poiché gli array µl non possono essere referenziati, il puntatore è esplicitamente a questa variabile, proprio all'indirizzo della crocetta in memoria. Tecnicamente, tutti questi test sono un tentativo di confrontare due variabili regolari. Questa è la proprietà dello svolgimento delle funzioni, nel mio esempio 4 funzioni perdono 0 funzioni, 3 delle quali sono proprio nel corpo del ciclo, cioè c'è un confronto di 40000000000 chiamate di funzione contro nessuna. E vediamo una differenza implicita che è troppo piccola da notare - perché sta mettendo del codice nel file eseguibile.... stiamo confrontando la stessa cosa.

E tutti questi calcoli - più sono complicati, meno hanno senso.

È più facile fare un esempio in cui in un caso chiamiamo cento funzioni, funzioni dentro funzioni... E nell'altro caso, tutto questo in forma espansa - e non ci sarà alcuna differenza. Poiché ArraySize(mas)== mas[].dimensione

Документация по MQL5: Операции с массивами / ArraySize
Документация по MQL5: Операции с массивами / ArraySize
  • www.mql5.com
"Нулевое измерение = Размер массива / (Первое измерение * Второе измерение * Третье измерение)"
 

Anche se per qualche ragione l'esempio di pi greco ha una differenza ..... per frequenza di overshoot, (redazione) anche se questo è puramente casuale overshoot

ed è uguale a 1ms per 1 miliardo di uscite, anche se questo non è esplicitamente provato confrontando variabile per variabile e la dispersione diventa ancora più grande))


 
Alexandr Andreev:

Non c'è una chiara differenza con questi calcoli. Metti tutto in un codice, e i risultati sono diversi, ce ne sono alcuni dove vince la prima opzione

)) Ogni array in µl ha una variabile responsabile della dimensione corrente dell'array, quindi nella maggior parte dei linguaggi.

La funzione ArraySize dice al compilatore di restituire il valore di questa variabile, cioè sostituisce questa variabile invece di questa funzione. Poiché gli array µl non possono essere referenziati, il puntatore è esplicitamente a questa variabile, proprio all'indirizzo della crocetta in memoria. Tecnicamente, tutti questi test sono un tentativo di confrontare due variabili regolari. Questa è la proprietà dello svolgimento delle funzioni, nel mio esempio 4 funzioni perdono 0 funzioni, 3 delle quali sono proprio nel corpo del ciclo, cioè c'è un confronto di 40000000000 chiamate di funzione contro nessuna. E vediamo una differenza implicita che è troppo piccola da notare - perché sta mettendo del codice nel file eseguibile.... stiamo confrontando la stessa cosa.

E tutti questi calcoli - più sono complicati, meno hanno senso.

È più facile fare un esempio in cui in un caso chiamiamo cento funzioni, funzioni dentro funzioni... E nell'altro caso, tutto questo in forma espansa - e non ci sarà alcuna differenza. Poiché ArraySize(mas)== mas[].dimensione

Non importa cosa viene eseguito nel corpo del ciclo. Questo è solo un carico per il test.
Gli esempi confrontano il riferimento a una funzione o variabile nella condizione di loop.

Non sono un assemblatore, ma penso che non sia la stessa cosa dal punto di vista delle istruzioni dell'assemblatore.
E se è anche avvolto in una classe, non è certo la stessa cosa.

Una funzione ha un'istruzione extra per recuperare un valore da una cella di memoria, cioè la funzione chiama la cella di memoria per un valore e solo allora restituisce il risultato.
Una variabile ha già questo valore, la variabile non fa riferimento da nessuna parte, restituisce il risultato immediatamente.

 
Roman:

Non importa cosa viene eseguito nel corpo del ciclo. È solo un carico per il test.
Gli esempi confrontano il riferimento a una funzione o variabile nella condizione di loop.

Non sono esperto di assembler, ma penso che dal punto di vista delle istruzioni di assemblaggio non sia la stessa cosa.
E se è anche avvolto in una classe, non è certo la stessa cosa.

Una funzione ha un'istruzione extra per recuperare un valore da una cella di memoria, cioè la funzione chiama la cella di memoria per un valore e solo allora restituisce il risultato.
Una variabile ha già quel valore, la variabile non fa riferimento da nessuna parte, restituisce il risultato immediatamente.

) Beh, non è così che funziona)

 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   int mas[];
   int mas1[300];
   int mas2[300];
   int mas3[300];
   int mas4[300];
   int mas5[300];
   int mas6[300];
   int z=300;
   int size=100000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100; 
   int t=0;
   int tr=0; 
   MathSrand(10);
    int num_steps=ArraySize(mas);
    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
     int v=size;
    ulong t1 = GetMicrosecondCount();
     
    
  // for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); i++)
        { 
        r2+=ArraySize(mas);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2=r2/10;
        }

     }  
   ulong t2=GetMicrosecondCount();
   //for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<v; i++)
        { 
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1=r1/10;
        }
     }
   
   int pi2 = sum*step;
   ulong t3=GetMicrosecondCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",pi," ",pi2);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

Quasi ogni corsa il leader cambia

il più lungo è la divisione)))

Motivazione: