forked from rosh/MQL5Book
149 lines
5.1 KiB
MQL5
149 lines
5.1 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| ArrayCapacity.mq5 |
| |
//| Copyright 2021, MetaQuotes Ltd. |
| |
//| https://www.mql5.com |
| |
//+------------------------------------------------------------------+
| |
| |
//+------------------------------------------------------------------+
| |
//| Dynamic array mockup (simulation in MQL5) |
| |
//+------------------------------------------------------------------+
| |
template<typename T>
| |
struct DynArray
| |
{
| |
int size;
| |
int capacity;
| |
T memory[];
| |
T operator[](int i)
| |
{
| |
if(i < 0 || i >= size)
| |
{
| |
PrintFormat("Index out of bounds: %d, size: %d", i, size);
| |
return NULL;
| |
}
| |
return memory[i];
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Resize DynArray with optional reserve |
| |
//+------------------------------------------------------------------+
| |
template<typename T>
| |
int DynArrayResize(DynArray<T> &array, int size, int reserve = 0)
| |
{
| |
if(size > array.capacity)
| |
{
| |
static int temp;
| |
temp = array.capacity;
| |
long ul = (long)GetMicrosecondCount();
| |
array.capacity = ArrayResize(array.memory, size + reserve);
| |
array.size = MathMin(size, array.capacity);
| |
ul -= (long)GetMicrosecondCount();
| |
PrintFormat("Reallocation: [%d] -> [%d], done in %d µs", temp, array.capacity, -ul);
| |
}
| |
else
| |
{
| |
array.size = size;
| |
}
| |
return array.size;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Get requested size of DynArray |
| |
//+------------------------------------------------------------------+
| |
template<typename T>
| |
int DynArraySize(DynArray<T> &array)
| |
{
| |
return array.size;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Free DynArray |
| |
//+------------------------------------------------------------------+
| |
template<typename T>
| |
void DynArrayFree(DynArray<T> &array)
| |
{
| |
ArrayFree(array.memory);
| |
ZeroMemory(array);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Script program start function |
| |
//+------------------------------------------------------------------+
| |
void OnStart()
| |
{
| |
ulong start = GetTickCount();
| |
ulong now;
| |
int count = 0;
| |
| |
DynArray<double> a;
| |
| |
// Check how fast the variant with memory reservation works
| |
Print("--- Test Fast: ArrayResize(arr,100000,100000)");
| |
| |
DynArrayResize(a, 100000, 100000);
| |
| |
for(int i = 1; i <= 300000 && !IsStopped(); i++)
| |
{
| |
// Set new array size specifying the reserve of 100,000 elements!
| |
DynArrayResize(a, i, 100000);
| |
// When reaching a round number, show the array size and the time spent
| |
if(DynArraySize(a) % 100000 == 0)
| |
{
| |
now = GetTickCount();
| |
count++;
| |
PrintFormat("%d. ArraySize(arr)=%d Time=%d ms", count, DynArraySize(a), (now - start));
| |
start = now;
| |
}
| |
}
| |
DynArrayFree(a);
| |
| |
// Now show, how slow the version without memory reservation is
| |
count = 0;
| |
start = GetTickCount();
| |
Print("---- Test Slow: ArrayResize(slow,100000)");
| |
| |
DynArrayResize(a, 100000, 100000);
| |
| |
for(int i = 1; i <= 300000 && !IsStopped(); i++)
| |
{
| |
// Set new array size, but with 100 times smaller reserve: 1000
| |
DynArrayResize(a, i, 1000);
| |
// When reaching a round number, show the array size and the time spent
| |
if(DynArraySize(a) % 100000 == 0)
| |
{
| |
now = GetTickCount();
| |
count++;
| |
PrintFormat("%d. ArraySize(arr)=%d Time=%d ms", count, DynArraySize(a), (now - start));
| |
start = now;
| |
}
| |
}
| |
| |
/*
| |
output (example/excerpt)
| |
| |
--- Test Fast: ArrayResize(arr,100000,100000)
| |
Reallocation: [0] -> [200000], done in 17 µs
| |
1. ArraySize(arr)=100000 Time=0 ms
| |
2. ArraySize(arr)=200000 Time=0 ms
| |
Reallocation: [200000] -> [300001], done in 2296 µs
| |
3. ArraySize(arr)=300000 Time=0 ms
| |
---- Test Slow: ArrayResize(slow,100000)
| |
Reallocation: [0] -> [200000], done in 21 µs
| |
1. ArraySize(arr)=100000 Time=0 ms
| |
2. ArraySize(arr)=200000 Time=0 ms
| |
Reallocation: [200000] -> [201001], done in 1838 µs
| |
Reallocation: [201001] -> [202002], done in 1994 µs
| |
Reallocation: [202002] -> [203003], done in 1677 µs
| |
Reallocation: [203003] -> [204004], done in 1983 µs
| |
Reallocation: [204004] -> [205005], done in 1637 µs
| |
...
| |
Reallocation: [295095] -> [296096], done in 2921 µs
| |
Reallocation: [296096] -> [297097], done in 2189 µs
| |
Reallocation: [297097] -> [298098], done in 2152 µs
| |
Reallocation: [298098] -> [299099], done in 2767 µs
| |
Reallocation: [299099] -> [300100], done in 2115 µs
| |
3. ArraySize(arr)=300000 Time=219 ms
| |
| |
*/
| |
}
| |
//+------------------------------------------------------------------+
|