Errors, bugs, questions - page 2667

 
So the bug I described isn't of interest to the developers, OK...
 
MT5 bug (build 2345) for a long time I couldn't understand why profiler is running and working, but no results are displayed anywhere.
It turns out that profiler for script project displays results only when optimization is disabled, if optimization is enabled, everything runs, works, but without any results.
 
Sergey Dzyublik:
I had a bug of MT5 (build 2345) and did not understand why the profiler is running and working but no results are displayed.
It turns out that profiler for script project shows results only when optimization is disabled, if optimization is enabled then everything will run and work but without any result.

Profiler does not work for all indicators (without optimization). I wrote about it twice on forum, sent code to developers in PM - no answer.

 
I worked with the profiler in MT5 (build 2345),
Roughly speaking, I was wondering why two algorithms giving the same result in the end run at different speeds, a 1.7x drawdown in optimization mode.

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


As a result we gained practical experience with the MT5 profiler and detected a number of bugs in its operation.
As it is not clear whether the developers are interested in this information, and there is no desire to spend hours of time for localization of bugs, only brief information on the detected problems will be given:

1) There is no way to compare speeds of different algorithms.
So an algorithm that is three times faster than others, both with optimization enabled and without, may appear the slowest in the profiler.
Apparently there is some sort of profiler overhead, which affects the execution time of algorithms, in this case, there is no point in comparing the performance speed of algorithms in profiler.

2) Incorrect Count value in the histogram tooltips on the screen.
The profiler says that the function was started 80K times and not 20K times as expected, at the same time inside the function for different lines exceeds Count several times, for some lines three times and for others two times.

3) Incorrect value of Time in histogram tooltips on the screen.
There are cases when the profiler shows that the algorithm entered the condition 99.90% of times, and it actually happens only once out of 20K passages.

 

It's not a bug, it's more of an observation!


mt 5 build 2340.

Yesterday when I opened Data Directory I didn't notice how the Indicators folder was moved to the Experts folder. Then I disabled mt5 and enabled it today, the indicators can also be used from the Navigator as if nothing had happened. However, if I reopen the Data Folder, an empty Indicators folder will appear and if I move some indicator to it, it will not appear in Navigator. It will not appear in the Navigator. Return of the Indicators folder back to MQL5\Indicators solves the problem.

 

MT5 (build 2347) Why such a big overhead when adding one element at a time to an array using ArrayResize, if memory has been reserved for them in advance?

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

Please consider improving the internal reservation algorithm with ArrayResize.

For example, for classes we can assume that they perform some kind of "internal registering in lists" in addition to calling the constructor.
And within the framework of reservation with ArrayResize, apart from direct memory allocation, you can try to optimize the process:
- take data from the adjacent created element (e.g. pointer to a virtual function table);
- pre-execute or reserve space for "internal registration" of classes that have not yet been created;

 
Sergey Dzyublik:

MT5 (build 2347) Why such a big overhead when adding one element at a time to an array using ArrayResize, if memory has been reserved for them in advance?

Even that doesn't help.

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

It just doesn't make any sense. Instead of speeding up, it's just slowing down.


ZZZ Strange, the result of the example from the Documentation is 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 :
Worked with profiler in MT5 (build 2345),
Roughly speaking, I was wondering why two algorithms, giving the same result in the end, run with different speed, a drawdown of 1.7 times in optimization mode.


...

Unfortunately, this long time profiler is useless for any important project. I already tried to report this, but there was no interest from the developers.
 
Sergey Dzyublik :

MT5 (build 2347) Why such a big overhead when adding one element at a time to an array using ArrayResize, if memory has been reserved for them in advance?

If you want to compare, it should be:

 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:

If you want to compare, it should be:

On my side the comparison was what it was supposed to be.
I know how many elements will be placed in the array and instead of creating them all at once I reserve memory for the uncreated ones.
The problem is, if I reserve memory and create array elements one by one, it takes many times longer than just creating them all at once.
So for structures it is 7 times slower.
And it is twice slower for the class and int data types.

This is a very big difference, which I think developers can eliminate if they wish.

Reason: