Errori, bug, domande - pagina 2879

 
Igor Makanu:

L'ho rielaborato un po

(è meglio non usare una macro in questo modo ;)

#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count;_i++){EX;} \
                                              printf("%s: loops=%llu ms=%llu",msg,count,GetMicrosecondCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
{
   ulong sum = 0;
   uint in01A = (uint)rand();
   uint in01B = (uint)rand();
   uint in02A = (uint)rand();
   uint in02B = (uint)rand();
   uint in03A = (uint)rand();
   uint in03B = (uint)rand();
   uint in04A = (uint)rand();
   uint in04B = (uint)rand();
   uint in05A = (uint)rand();
   uint in05B = (uint)rand();
   uint param[5];
   SpeedTest(22, "tst 1 : ",
   {
      sum += in01A << (sizeof(ushort) * 8) | in01B;
      sum += in02A << (sizeof(ushort) * 8) | in02B;
      sum += in03A << (sizeof(ushort) * 8) | in03B;
      sum += in04A << (sizeof(ushort) * 8) | in04B;
      sum += in05A << (sizeof(ushort) * 8) | in05B;
   //   for(int i = 0; i < 5; i++) sum += param[i];
   });
   Print(sum);
   }
//--  

   ulong sum = 0;
   ushort in00 = (ushort)rand();
   ushort in01 = (ushort)rand();
   ushort in02 = (ushort)rand();
   ushort in03 = (ushort)rand();
   ushort in04 = (ushort)rand();
   ushort in05 = (ushort)rand();
   ushort in06 = (ushort)rand();
   ushort in07 = (ushort)rand();
   ushort in08 = (ushort)rand();
   ushort in09 = (ushort)rand(); 
   sum = 0;
   union ushortTouint
   {
      uint param[5];
      ushort in[10];
   }U;
      ushortTouint u;
   SpeedTest(22, "tst 2 : ",
   { 
      u.in[0] = in00;
      u.in[1] = in01;
      sum +=u.param[0];
      u.in[2] = in02;
      u.in[3] = in03;
      sum +=u.param[1];
      u.in[4] = in04;
      u.in[5] = in05;
      sum +=u.param[2];
      u.in[6] = in06;
      u.in[7] = in07;
      sum +=u.param[3];
      u.in[8] = in08;
      u.in[9] = in09;
      sum +=u.param[4];
    //  Comment(121);
   //  for(int i = 0; i < 5; i++) sum += u.param[i];
   });
Print(sum);
}
 
Alexandr Andreev:

L'ho rielaborato un po

(quindi è meglio non usare macro ;)

Quando faccio i test, confondo il codice il più possibile per evitare che l'ottimizzatore butti fuori dei cicli vuoti

avete

 //  for(int i = 0; i < 5; i++) sum += u.param[i];

L'ottimizzazione dell'esecuzione MQL può terminare il primo ciclo in anticipo, poiché i valori calcolati non vengono utilizzati, quindi qualcosa dovrebbe essere fatto dopo lo SpeedTest() con i risultati - questo ciclo

Ho controllato con il ciclo commentato, non l'ho buttato via, ma nell'altro test potrei andare in crash


La macro è una questione di gusto, l'ho provata molte volte e funziona, non vedo il senso di scrivere la stessa cosa a mano



UPD: trovato dove ho letto come funzionano i compilatori moderni ora, abbastanza informativo

https://habr.com/ru/post/431688/

https://habr.com/ru/post/47878/

 

il codice dà il valore iRSI di handles e tps sempre solo 10, ma i prezzi e il grafico cambiano, anche.

iRSI(_Symbol,PERIOD_H1,14,PRICE_CLOSE)


costruire 2652

Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Периоды графиков
Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Периоды графиков
  • www.mql5.com
Все предопределенные периоды графиков имеют уникальные идентификаторы. Идентификатор PERIOD_CURRENT означает текущий период графика, на котором запущена mql5-программа.
 
Aleksei Skrypnev:

il codice dà il valore iRSI di handles e tps sempre solo 10, ma i prezzi e il grafico cambiano, anche.

iRSI(_Symbol,PERIOD_H1,14,PRICE_CLOSE)


costruire 2652

Hai la maniglia dell'indicatore, è il 10

Poi, è necessario ottenere i valori sulla barra di destra

//--- создадим хэндл индикатора
   if(type==Call_iRSI)
      handle=iRSI(name,period,ma_period,applied_price);

//--- индикаторный буфер
double  rsi_buffer[];

//--- заполняем часть массива iRSIBuffer значениями из индикаторного буфера под индексом 0
   if(CopyBuffer(ind_handle,0,0,amount,rsi_buffer)<0)
     {
      //--- если копирование не удалось, сообщим код ошибки
      PrintFormat("Не удалось скопировать данные из индикатора iRSI, код ошибки %d",GetLastError());
      //--- завершим с нулевым результатом - это означает, что индикатор будет считаться нерассчитанным
      return(false);
     }

Leggete la guida, o cercate le risposte sul forum - sono molte

Документация по MQL5: Технические индикаторы / iRSI
Документация по MQL5: Технические индикаторы / iRSI
  • www.mql5.com
//|                                                    Demo_iRSI.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                             https://www.mql5.com | //| Перечисление способов создания хэндла                            |  Creation             type=Call_iRSI;               ...
 
Vitaly Muzichenko:

Hai la maniglia dell'indicatore, è il 10

Poi, è necessario ottenere i valori sulla barra di destra

Leggete la guida, o cercate le risposte sul forum - ce ne sono molte

Capito. Studierò i buffer. È strano, avevo la sensazione che tutto dovesse funzionare così com'è, forse l'ho confuso con mql4.

La cosa strana è che l'ho cercato su Google e non sono riuscito a trovarlo in mql5 per ottenere i dati dell'indicatore.


Aha, secondo il tuo esempio come ho capito il valore dell'indicatore RSI è alla fine in una variabile della seguente forma

rsi_buffer[0] 
 
Igor Makanu:

controllato:

2020.10.15 21:48:01.401 SpeedTst (EURUSD,H1) tst 1 : : : loops=10000000000 ms=10864370

2020.10.15 21:48:12.264 SpeedTst (EURUSD,H1) tst 2 : : : loops=10000000000 ms=10862287

la differenza non è significativa, è altamente probabile che se cambiamo i test nell'ordine opposto, i risultati saranno opposti

non critico

non è affatto giusto includere rand() nel test poiché questa funzione consuma molte più risorse degli altri comandi.
Penso che questo sarebbe un test più corretto:

#define  Num 1000000
#define  SpeedTest(msg,s,EX)  {ulong mss=GetMicrosecondCount(); EX \
                                    mss=GetMicrosecondCount()-mss;\
                                    printf("%-22s%llu µs; Сумма - %llu",msg,mss,s);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   ulong sum = 0;
   ushort in[];
   ArrayResize(in,Num*2);
   for (int i=0; i<Num*2; i++) in[i] = (ushort)rand();
   SpeedTest("test binary shift : ", sum,
   for (int i =0;i<(2*Num-1) && !_StopFlag;i+=2)
   {
      sum+=in[i]<<(sizeof(ushort)*8) | in[i+1];
   });
//--   
   sum = 0;
   union ushortTouint
   {
      uint param;
      ushort in[2];
   } u;
   SpeedTest("test union : ", sum,
   for (int i =0;i<(2*Num-1) && !_StopFlag;i+=2)
   {
      u.in[0]=in[i+1];
      u.in[1]=in[i];
      sum+=u.param;
   });
}

Risultato:

2020.10.15 17:14:03.168 TestMakanu (USDCAD,M1)  test binary shift :   1384 µs; Сумма - 1074434582054198
2020.10.15 17:14:03.169 TestMakanu (USDCAD,M1)  test union :          1209 µs; Сумма - 1074434582054198
2020.10.15 17:14:19.370 TestMakanu (USDCAD,M1)  test binary shift :   1891 µs; Сумма - 1073924616844949
2020.10.15 17:14:19.371 TestMakanu (USDCAD,M1)  test union :          1289 µs; Сумма - 1073924616844949
2020.10.15 17:14:20.949 TestMakanu (USDCAD,M1)  test binary shift :   1342 µs; Сумма - 1073194788831653
2020.10.15 17:14:20.950 TestMakanu (USDCAD,M1)  test union :          1178 µs; Сумма - 1073194788831653
2020.10.15 17:14:27.141 TestMakanu (USDCAD,M1)  test binary shift :   1365 µs; Сумма - 1075017290553168
2020.10.15 17:14:27.142 TestMakanu (USDCAD,M1)  test union :          1362 µs; Сумма - 1075017290553168
2020.10.15 17:14:28.202 TestMakanu (USDCAD,M1)  test binary shift :   1354 µs; Сумма - 1075051817914563
2020.10.15 17:14:28.203 TestMakanu (USDCAD,M1)  test union :          1105 µs; Сумма - 1075051817914563

Per fortuna, alla fine l'ho messo sul cavallo sbagliato. I sindacati sono un po' più veloci. Sono più convenienti per lavorare e il codice è più leggibile.

 
Nikolai Semko:

è difficilmente corretto includere rand() nel test, poiché questa funzione è un ordine di grandezza più dispendioso in termini di risorse degli altri comandi.

per niente critico

Il tempo di esecuzione di rand() è costante, molto probabilmente è una comune funzione C++, cercate su google "rand c++ source code"

dovete inizializzarlo, ma se lo inizializzate con delle costanti potreste incontrare un'ottimizzazione

in generale, non capisco l'antipatia di rand()

un'opzione è quella di inizializzare con qualcosa come questo:

void OnStart()
{
   for(int i=0;i<20;i++) Print(Myvalue());

}
//+------------------------------------------------------------------+
int Myvalue()
{
   const static int arr[] = {3, 1, 4, 1, 5, 9, 2, 6};
   static int cnt = ArraySize(arr);
   if(--cnt < 0) cnt = ArraySize(arr) - 1;
   return(arr[cnt]);
}

sarebbe veloce.


ha eseguito il tuo script, imho non corretto.

Il tempo principale è il caricamento del codice nella cache e poi nel processore

e aggiungere la discrezione del timer del sistema

otteniamo... quasi un numero casuale.

è necessario testarlo a lungo, circa 100500 volte, imho

 
Nikolai Semko:

È improbabile che sia corretto includere rand() nel test, poiché questa funzione consuma un ordine di grandezza più risorse degli altri comandi.
Penso che questo sarebbe un test più corretto:

Risultato:

Per fortuna, alla fine ho scommesso sul cavallo sbagliato. I sindacati sono un po' più veloci. Sono più convenienti per lavorare e il codice è più leggibile.


Una volta per una volta, e a distanza della prima vittoria, (come il primo metodo ha rimosso la linea di conversione da breve a qualcosa)

 
Igor Makanu:

per niente critico

Il tempo di esecuzione di rand() è costante, molto probabilmente è una comune funzione C++, cercate su google "rand c++ source code"

dovete inizializzarlo, ma se lo inizializzate con delle costanti potreste incontrare un'ottimizzazione

in generale, non capisco l'antipatia di rand()

come variante da inizializzare con qualcosa del genere:

sarà veloce

Il punto è che si dovrebbe misurare esattamente ciò che è necessario misurare, senza roba estranea.

 
Alexandr Andreev:

Il punto era di misurare esattamente ciò che è richiesto, senza extra

no

Se ci sono frammenti di codice ripetuti, si otterranno test di ottimizzazione!

Che differenza fa la durata di esecuzione di rand()?

lasciare che venga eseguito 2/3 del tempo di test, la cosa principale è che il tempo di rand() sia costante

Il vostro codice MQL userà le funzioni MQL del sistema, giusto? - che senso ha testare un codice perfetto?

Motivazione: