Features of the mql5 language, subtleties and tricks - page 263

 

Forum on trading, automated trading systems and testing trading strategies

Errors, bugs, questions

Andrey Dik, 2024.06.05 07:59

The reference book on working with the ArrayResize function says the following:

Note

The function can be applied only to dynamic arrays. Note that you cannot resize dynamic arrays assigned as indicator buffers by SetIndexBuffer(). For indicator buffers all operations on resizing are performed by the terminal executing subsystem.

The total number of elements in the array cannot exceed 2147483647.

In case of frequent memory allocation, it is recommended to use the third parameter setting the reserve to reduce the amount of physical memory allocation. All subsequent calls of theArrayResizefunction do not result in physical memory allocation, but only change the size of the first array dimension within the reserved memory. Keep in mind that the third parameter will only be used when physical memory allocation occurs, e.g.:

ArrayResize(arr,1000,1000);
for(int i=1;i<3000;i++)
ArrayResize(arr,i,1000);

In this case there will be 2 memory reallocations, once before entering the loop for 3000 iterations with the array dimension set to 1000 and the second when i is equal to 2000. If the third parameter is omitted, there will be 2000 physical memory reallocations and it will slow down the execution of the programme.

I mistakenly thought that the third parameter would allocate memory for the array when the function is launched for the first time:

ArrayResize (a, 0, 10000);

but I was cruelly mistaken, this code does not allocate memory for the array. Memory is allocated only if the second parameter is not 0.

In my case, it should be done like this:

ArrayResize (a, 10000, 10000);
ArrayResize (a, 0, 10000);

or like this:

ArrayResize (a, 1, 10000);
ArrayResize (a, 0, 10000);

which is equivalent, or like this:

ArrayResize (a, 1, 10000);
ArrayResize (a, 0);

In my code examples here it is necessary that the programme works starting from the zero array size but with memory allocated in advance.


Thus, I ask the developers to add this point to the help that additional memory allocation for the array occurs only in case of non-zero second parameter.

I lost a lot of time trying to find out the reasons for the brakes, I could not imagine that the problem is here.


 
Artyom Trishkin #:

And how do I figure out how much memory to allocate in this function?

 
Vladimir Pastushak #:

And how do I figure out how much memory to allocate in this function?

Memory is allocated for the specified number of array cells. In other words, it is allocated for the specified size. And we know it approximately when writing the programme. This is an additional size.
The Help says when and how many times memory is reallocated.
 
Vladimir Pastushak #:

And how do I figure out how much memory to allocate in this function?

   Print(TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE));
   double arr[];
   ArrayResize(arr,1,1000000);
   Print(TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE));

Yes, indeed, if the second parameter is 1, then 8 MB is allocated.
If 0, then nothing is allocated

 
What is the advantage of allocating a larger volume and resizing it at each iteration to increase the size, compared to the option of creating the maximum array size (which may be necessary) and resizing it to the required size at the end of the loop? I mostly use the second option in my code.
 
Aleksey Vyazmikin array size (which may be necessary) and resizing it to the required size at the end of the loop? I mostly use the second option in my code.

There will be no resizing (physical redistribution).

Forum on trading, automated trading systems and testing trading strategies.

New version of MetaTrader 5 build 4230: more built-in applications and expanded ONNX support

fxsaber, 2024.03.05 18:13

void OnStart()
{
  MqlTick Ticks[];
  
  ArrayResize(Ticks, 5 e7);
  Print(MQLInfoInteger(MQL_MEMORY_USED)); // 2862
  
  ArrayResize(Ticks, 1);
  Print(MQLInfoInteger(MQL_MEMORY_USED)); // 2862
}
 
fxsaber #:

There will be no resysis (physical redistribution).

What is the point of it, if the whole array can be used?

If you need memory later, you can either copy the result to a separate array and clear the temporary one, or just clear it after processing.

I just really have not encountered such a need. If there is no memory for the maximum array, you can't do calculations, and if there is, it doesn't matter....

 
Aleksey Vyazmikin #:

What's the point of it if the whole array can be used?

Tick Multicurrency Tester. Request ticks for one symbol at a time (50% RAM), then filter them (10% RAM). Same for other symbols. If the ticks are not physically shrunk in the filter, there is a memory shortage at the data preparation stage.

 
Nikolai Semko #:

Yes, indeed, if the second parameter is 1, then 8 MB is allocated.
If 0, then nothing is allocated.

It is not quite clear here.

How much memory to allocate, how to calculate it?

 
Vladimir Pastushak #:

It's not quite clear here.

How much memory to allocate, how to calculate?

The program logic should know in advance how many cells the array may need. Usually there is an understanding for each particular algorithm, with what step to reserve memory. Too small a step of the reserve is a slowdown of the programme, too big is a waste in memory consumption.