Errori, bug, domande - pagina 2667

 
Quindi il bug che ho descritto non è di interesse per gli sviluppatori, OK...
 
MT5 bug (build 2345) per molto tempo non riuscivo a capire perché il profiler è in esecuzione e funziona, ma nessun risultato viene visualizzato da nessuna parte.
Risulta che il profiler per il progetto di script mostra i risultati solo quando l'ottimizzazione è disabilitata, se l'ottimizzazione è abilitata, tutto viene eseguito, funziona, ma senza alcun risultato.
 
Sergey Dzyublik:
Ho avuto un bug di MT5 (build 2345) e non ho capito perché il profiler è in esecuzione e funziona ma non vengono visualizzati risultati.
Risulta che il profiler per il progetto di script mostra i risultati solo quando l'ottimizzazione è disabilitata, se l'ottimizzazione è abilitata allora tutto verrà eseguito e funzionerà ma senza alcun risultato.

Profiler non funziona per tutti gli indicatori (senza ottimizzazione). L'ho scritto due volte sul forum, ho inviato il codice agli sviluppatori in PM - nessuna risposta.

 
Ho lavorato con il profiler in MT5 (build 2345),
Grosso modo, mi chiedevo perché due algoritmi che danno lo stesso risultato alla fine a velocità diverse, un drawdown di 1,7x in modalità di ottimizzazione.

#include <stl_vector.mqh>

// TickCounts: 850
vector<int>::move test_vector_move_return_assign_by_index(int n){
   vector<int> v(n);
   for(int i = 0; i < n; i++){
      v[i].UNREF  = i;
   }
   return v;
};

// TickCounts: 1450
vector<int>::move test_vector_move_return_push_back(int n){
   vector<int> v;
   // lazy implementation  
   v.reserve(n);                      
   for(int i = 0; i < n; i++){
      v.push_back(i);
   }
   return v;
};


void OnStart()
{
   for(int i = 0; i < 20000; i++){
       vector<int> v_int_move = test_vector_move_return_assign_by_index(1000);
   }
   
   for(int i = 0; i < 20000; i++){
      vector<int> v_int_move = test_vector_move_return_push_back(1000);
   }
}


Come risultato abbiamo acquisito esperienza pratica con il profilatore MT5 e abbiamo individuato una serie di difetti nel suo funzionamento.
Poiché non è chiaro se gli sviluppatori sono interessati a queste informazioni, e non c'è il desiderio di spendere ore di tempo per la localizzazione dei bug, verranno date solo brevi informazioni sui problemi rilevati:

1) Non c'è modo di confrontare le velocità di diversi algoritmi.
Così un algoritmo che è tre volte più veloce degli altri, sia con l'ottimizzazione abilitata che senza, può apparire il più lento nel profiler.
Apparentemente c'è una sorta di overhead del profiler, che influenza il tempo di esecuzione degli algoritmi, in questo caso, non ha senso confrontare la velocità delle prestazioni degli algoritmi nel profiler.

2) Valore di conteggio errato nei tooltip dell'istogramma sullo schermo.
Il profiler dice che la funzione è stata avviata 80K volte e non 20K volte come previsto, allo stesso modo il conteggio è superato di volte per diverse stringhe, tre volte per alcune stringhe e due volte per altre.

3) Valore errato di Time nei tooltip dell'istogramma sullo schermo.
Ci sono casi in cui il profiler mostra che l'algoritmo è entrato nella condizione il 99,90% delle volte, e in realtà accade solo una volta su 20K passaggi.

 

Non è un bug, è più un'osservazione!


mt 5 build 2340.

Ieri quando ho aperto Data Directory non ho notato che la cartella Indicators è stata spostata nella cartella Experts. Poi ho disabilitato mt5 e l'ho abilitato oggi, gli indicatori possono essere utilizzati anche dal Navigatore come se nulla fosse successo. Tuttavia, se riapro la cartella Data Folder, appare una cartella Indicators vuota e se vi sposto qualche indicatore, questo non appare in Navigator. Non apparirà nel Navigatore. Il ritorno della cartella Indicators a MQL5\Indicators risolve il problema.

 

MT5 (build 2347) Perché un overhead così grande quando si aggiunge un elemento alla volta a un array usando ArrayResize, se la memoria è stata riservata per loro in anticipo?

#define  K 1000
#define  M (1000 * K)

#define    SpeedTest(test_count,msg,EX)        {uint mss=GetTickCount(); ulong count=test_count;for(ulong ii=0;ii<count&&!_StopFlag;ii++){EX;} \
                                              printf("%-60s: loops=%i ms=%u",msg,count,GetTickCount()-mss);}
                                              
class A{
public:
   int data;
};

struct B{
   int data;
};

template<typename T>
void test1(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize all",
   {
      T class_array[];
      for(int i = 1; i <= array_size; i++){
         ArrayResize(class_array, array_size);
      }
   }
   )
};

template<typename T>
void test2(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize one by one with reserved memory",
   {
      T class_array[];
      ArrayResize(class_array, 1, array_size - 1);
      for(int i = 2; i <= array_size; i++){
         ArrayResize(class_array, i);
      }
   }
   )
};

void OnStart()
{
  const int test_count = 5*K;
  const int array_size = 5*K;  
  
  test1<int>(test_count, array_size);            // Avg time: 100
  test2<int>(test_count, array_size);            // Avg time: 190
  test1<int>(test_count, array_size);
  test2<int>(test_count, array_size);
  test1<int>(test_count, array_size);
  test2<int>(test_count, array_size);
  test1<int>(test_count, array_size);
  test2<int>(test_count, array_size);
  
printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  test1<A>(test_count, array_size);              // Avg time: 810
  test2<A>(test_count, array_size);              // Avg time: 1460
  test1<A>(test_count, array_size);
  test2<A>(test_count, array_size);
  test1<A>(test_count, array_size);
  test2<A>(test_count, array_size);
  test1<A>(test_count, array_size);
  test2<A>(test_count, array_size);
  
printf("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
  test1<B>(test_count, array_size);              // Avg time: 110
  test2<B>(test_count, array_size);              // Avg time: 770
  test1<B>(test_count, array_size);
  test2<B>(test_count, array_size);
  test1<B>(test_count, array_size);
  test2<B>(test_count, array_size);
  test1<B>(test_count, array_size);
  test2<B>(test_count, array_size);
}

Si prega di considerare il miglioramento dell'algoritmo interno di prenotazione con ArrayResize.

Per esempio, per le classi possiamo supporre che eseguano qualche tipo di "registro interno nelle liste" oltre alla chiamata del costruttore.
E nel quadro della prenotazione con ArrayResize, oltre all'allocazione diretta della memoria, si può cercare di ottimizzare il processo:
- prendere i dati dall'elemento creato adiacente (ad esempio il puntatore a una tabella di funzioni virtuali);
- pre-eseguire o riservare spazio per la "registrazione interna" di classi che non sono ancora state create;

 
Sergey Dzyublik:

MT5 (build 2347) Perché un overhead così grande quando si aggiunge un elemento alla volta a un array usando ArrayResize, se la memoria è stata riservata per loro in anticipo?

Anche questo non aiuta.

      ArrayResize(class_array, 1, array_size - 1);
      for(int i = 0; i < array_size; i++){
//         ArrayResize(class_array, i);
         ArrayResize(class_array, i, array_size - 1);

Non ha alcun senso. Invece di accelerare, sta solo rallentando.


ZZ È strano, il risultato dell'esecuzione dell'esempio della documentazione è zero.

--- Test Fast: ArrayResize(arr,100000,100000)
1. ArraySize(arr)=100000 Time=0 ms
2. ArraySize(arr)=200000 Time=0 ms
3. ArraySize(arr)=300000 Time=0 ms
---- Test Slow: ArrayResize(slow,100000)
1. ArraySize(slow)=100000 Time=0 ms
2. ArraySize(slow)=200000 Time=0 ms
Документация по MQL5: Операции с массивами / ArrayResize
Документация по MQL5: Операции с массивами / ArrayResize
  • www.mql5.com
При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры. Если ArrayResize() применена к статическому массиву, таймсерии или индикаторному буферу, то размер массива остается прежним – такие массивы не могут быть...
 
Sergey Dzyublik :
Ha funzionato con il profiler in MT5 (build 2345),
Grosso modo, mi chiedevo perché due algoritmi, che danno lo stesso risultato alla fine, girano a velocità diverse, il drawdown è 1,7 volte in modalità ottimizzazione.


...

Sfortunatamente, questo lungo profiler è inutile per qualsiasi progetto importante. Ho già provato a segnalarlo, ma non c'è stato alcun interesse da parte degli sviluppatori.
 
Sergey Dzyublik :

MT5 (build 2347) Perché un overhead così grande quando si aggiunge un elemento alla volta a un array usando ArrayResize, se la memoria è stata riservata per loro in anticipo?

Se volete fare un paragone, dovrebbe essere così:

 void test1 ( const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize all",
   {
      T class_array[];
       for ( int i = 0 ; i < array_size; i++){
         ArrayResize (class_array,  i );
      }
   }
   )
 
Alain Verleyen:

Se volete fare un paragone, dovrebbe essere così:

Dalla mia parte il confronto era quello che doveva essere.
So quanti elementi saranno messi nell'array e invece di crearli tutti in una volta riservo la memoria per quelli non creati.
Il problema è che se riservo la memoria e creo gli elementi dell'array uno per uno, ci vuole molto più tempo che crearli tutti insieme.
Quindi per le strutture è 7 volte più lento.
Ed è due volte più lento per i tipi di dati class e int.

Questa è una differenza molto grande, che credo che gli sviluppatori possano eliminare se lo desiderano.