Erros, bugs, perguntas - página 2667

 
Portanto, o bug que descrevi não é do interesse dos criadores.
 
MT5 bug (build 2345) durante muito tempo não consegui perceber porque é que o profiler está a funcionar e a funcionar, mas os resultados não são mostrados em lado nenhum.
Acontece que o perfilador para projecto de guião só exibe resultados quando a optimização está desactivada, se a optimização estiver activada, tudo funciona, mas sem quaisquer resultados.
 
Sergey Dzyublik:
Eu tinha um bug de MT5 (build 2345) e não percebi porque é que o profiler está a funcionar e a funcionar, mas não são apresentados resultados.
Acontece que o perfilador para projecto de guião só mostra resultados quando a optimização está desactivada, se a optimização estiver activada então tudo funcionará e funcionará, mas sem qualquer resultado.

O perfilador não funciona para todos os indicadores (sem optimização). Escrevi sobre isso duas vezes no fórum, enviei código aos programadores em PM - sem resposta.

 
Trabalhei com o profiler em MT5 (construção 2345),
Grosso modo, estava a pensar porquê dois algoritmos que dão o mesmo resultado no final de execução a velocidades diferentes, um drawdown de 1,7x no modo de optimização.

#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);
   }
}


Como resultado, adquirimos experiência prática com o profiler MT5 e detectámos uma série de defeitos no seu funcionamento.
Como não é claro se os criadores estão interessados nesta informação, e não há vontade de gastar horas de tempo para a localização de bugs, apenas serão dadas breves informações sobre os problemas detectados:

1) Não há forma de comparar as velocidades de diferentes algoritmos.
Assim, um algoritmo que é três vezes mais rápido do que outros, tanto com optimização activada como sem, pode aparecer o mais lento no perfilador.
Aparentemente, existe algum tipo de sobrecarga do profiler, que afecta o tempo de execução dos algoritmos, neste caso, não vale a pena comparar a velocidade de desempenho dos algoritmos no profiler.

2) Valor de contagem incorrecto nas pontas de ferramentas do histograma no ecrã.
O profiler diz que a função foi iniciada 80K vezes e não 20K vezes como esperado, da mesma forma a contagem é excedida por vezes para cordas diferentes, três vezes para algumas cordas e duas vezes para outras.

3) Valor incorrecto do Tempo nas pontas de ferramentas do histograma no ecrã.
Há casos em que o profiler mostra que o algoritmo entrou na condição 99,90% das vezes, e na realidade só acontece uma vez em 20K passagens.

 

Não é um insecto, é mais um comentário!


mt 5 construir 2340.

Ontem, quando abri o Directório de Dados, não reparei como a pasta de Indicadores foi movida para a pasta de Especialistas. Depois desabilitei o mt5 e activei-o hoje, os indicadores também podem ser utilizados a partir do Navegador como se nada tivesse acontecido. Contudo, se eu reabrir a Pasta de Dados, aparecerá uma pasta de Indicadores vazia e se eu mover algum indicador para ela, ele não aparecerá no Navigator. Não aparecerá no Navigator. O regresso da pasta de Indicadores à MQL5\Indicadores resolve o problema.

 

MT5 (build 2347) Porquê uma sobrecarga tão grande ao adicionar um elemento de cada vez a um array usando o ArrayResize, se a memória foi reservada para eles com antecedência?

#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);
}

Por favor, considere melhorar o algoritmo de reserva interna com o ArrayResize.

Por exemplo, para as aulas, podemos assumir que elas realizam algum tipo de "registo interno em listas", para além de chamar o construtor.
E no âmbito da reserva com ArrayResize, para além da alocação directa de memória, pode tentar optimizar o processo:
- retirar dados do elemento criado adjacente (por exemplo, ponteiro para uma tabela de funções virtual);
- pré-executar ou reservar espaço para "inscrição interna" de aulas que ainda não foram criadas;

 
Sergey Dzyublik:

MT5 (build 2347) Porquê uma sobrecarga tão grande ao adicionar um elemento de cada vez a um array usando o ArrayResize, se a memória foi reservada para eles com antecedência?

Mesmo isso não ajuda.

      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);

Simplesmente não faz qualquer sentido. Em vez de acelerar, está apenas a abrandar.


ZZZ Strange, o resultado do exemplo da Documentação é 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 :
Trabalhou com o profiler em MT5 (construção 2345),
Grosso modo, eu estava a pensar porque dois algoritmos, dando o mesmo resultado no final, funcionam a velocidades diferentes, um drawdown de 1,7 vezes no modo de optimização.


...

Infelizmente, este perfilador de longa data é inútil para qualquer projecto importante. Já tentei relatar isto, mas não houve interesse por parte dos promotores.
 
Sergey Dzyublik :

MT5 (build 2347) Porquê uma sobrecarga tão grande ao adicionar um elemento de cada vez a um array usando o ArrayResize, se a memória foi reservada para eles com antecedência?

Se quiser comparar, deve ser:

 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 quiser comparar, deve ser:

Do meu lado, a comparação era o que deveria ser.
Sei quantos elementos serão colocados na matriz e em vez de os criar todos de uma só vez, reservo a memória para os não criados.
O problema é que, se eu reservar memória e criar elementos de matriz um por um, leva muitas vezes mais tempo do que apenas criá-los todos de uma só vez.
Assim, para estruturas, é 7 vezes mais lento.
E é duas vezes mais lento para os tipos de dados de classe e int.

Esta é uma diferença muito grande, que acredito que os criadores podem eliminar se assim o desejarem.