Новая версия платформы MetaTrader 5 build 4230: больше встроенных приложений и расширение поддержки ONNX - страница 23

 
bred_bred1 #:

А с чего бы им работать в любом количестве - ваша запись в начале это запись инициализации массива. Правда массива нет, но это неважно ведь массив одномерен и имеет один элемент - по сути просто переменная со значением.
Когда вы вводите вторую пару скобок это запись инициализации многомерного массива, но поскольку он всё равно исходя из написанного одномерный и с одним элементом - в итоге опять просто переменная со значением.
А вот когда третья пара появляется тут уже непонятно что вы хотите этим сказать. Мне кажется так, но могу ошибаться.


Три и более пар скобок не противоречат Вашей теории, но работают только дае пары.
 
fxsaber #:

Случайно написал выделенную строку, компилятор не стал ругаться. Какое синтаксическое действие делает эта строка?

Следующие записи обнуления переменной на объявлении эквивалентны:

   int a=0;
   int b=int(0);
   int c={0};
   int d={};
   int e{};
 
Andrey Dik #:

Три и более пар скобок не противоречат Вашей теории, но работают только дае пары.

По мне так противоречат. Что вы вызываете тремя скобками?
В плюсах и на две-то ругается если ему массив не дать вместо просто int. А с тремя он даже с массивом не понимает что вы конкретно от него хочете и я тоже)

 
fxsaber #:

Дольше секунды ArrayResize отрабатывает, к сожалению.

Спасибо за сообщение!

Нашли способ ускорить работу, для данного кода, когда структура  не является объектом класса и не имеет сложных полей: динамических массивов, строк и объектов являющихся классами или имеющих сложные поля.

Тем не менее, т.к. массив не выделяется заново, а перевыделяется с меньшим размером, то в новый массив меньшего размера происходит копирование данных из старого (4e7*sizeof(MqlTick) байт) - это занимает какое-то время.

 
Ilyas #:

Тем не менее, т.к. массив не выделяется заново, а перевыделяется с меньшим размером, то в новый массив меньшего размера происходит копирование данных из старого (4e7*sizeof(MqlTick) байт) - это занимает какое-то время.

В меньшую же сторону идет ArrayResize, почему перевыделение?

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Новая версия платформы MetaTrader 5 build 4230: больше встроенных приложений и расширение поддержки ONNX

fxsaber, 2024.03.05 19:20

Дико долгое понижение размерности массива.

void OnStart()
{
  MqlTick Ticks[];
  
  {
    const ulong StartTime = GetMicrosecondCount();
    ArrayResize(Ticks, 5e7, -1);
    Print(GetMicrosecondCount() - StartTime); // 50
  }
  
  {
    const ulong StartTime = GetMicrosecondCount();
    ArrayResize(Ticks, 4e7, -1);
    Print(GetMicrosecondCount() - StartTime); // 1625808
  }


И почему не получается уменьшить потребление памяти при снижении ArrayResize?

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Новая версия платформы MetaTrader 5 build 4230: больше встроенных приложений и расширение поддержки ONNX

fxsaber, 2024.03.05 18:13

b4209, обнуление размера массива не уменьшает используемую память.
void OnStart()
{
  MqlTick Ticks[];
  
  ArrayResize(Ticks, 5e7);
  Print(MQLInfoInteger(MQL_MEMORY_USED)); // 2862
  
  ArrayResize(Ticks, 0);
  Print(MQLInfoInteger(MQL_MEMORY_USED)); // 2862

  ArrayFree(Ticks);
  Print(MQLInfoInteger(MQL_MEMORY_USED)); // 0
}
 
Ilyas #:

Нашли способ ускорить работу, для данного кода, когда структура не является объектом класса и не имеет сложных полей: динамических массивов, строк и объектов являющихся классами или имеющих сложные поля.

Что имеется в виду?
 
fxsaber #:

В меньшую же сторону идет ArrayResize, почему перевыделение?

Потому, что массив физически перестраивается и переносится в новую память.

И почему не получается уменьшить потребление памяти при снижении ArrayResize?

Потому, что в современных программах память не отдается в операционку сразу. Используются пулы памяти, с которыми и работает приложение.

Если каждый раз выдавать и забирать память у операционки через VirtualAlloc, то все будет экстремально медленно и скорее всего операционка убьется из-за фрагментации кучи мелкими запросами.


Вообще надо очень аккуратно относиться к перестроению массивов. Тем более, к автоматическому. Тем более, при огромных значениях.

Нужно использовать стратегию предварительного предвыделения, чтобы минимизировать любое перевыделение в последующем. Ну и лучше не уменьшать массивы - это практически всегда ошибочная стратегия. Используйте счетчики количества записей, не меняя внутренней структуры массива.

 
fxsaber #:
Что имеется в виду?

Перемещение сложных(структур, классов) элементов массива по сути означает вызов конструктора объекта в новом месте и последующим деструктором старого объекта.

И так для миллионов объектов в вашем примере. В вашем случае конструктор - это поэлементный memcpy каждой MqlTick структуры.

Мы оптимизируем случаи для простых типов. Есть несколько тактик для улучшения.

 
fxsaber #:

В меньшую же сторону идет ArrayResize, почему перевыделение?

И почему не получается уменьшить потребление памяти при снижении ArrayResize?

  1. к сожалению, вижу, что справка по ArrayResize не содержит описания для случая, когда reserve_size == -1
    это изменяет обычное поведение ArrayResize при уменьшении размера массива, происходит реальное перевыделение памяти, аналог C++ std::vector<>::shrink_to_fit()

  2. Что же Вы, то используете 3 параметр, то нет:
      MqlTick Ticks[];
      
      ArrayResize(Ticks, 5e7, -1);
      Print(MQLInfoInteger(MQL_MEMORY_USED)); // 2862
      
      ArrayResize(Ticks, 0, -1);
      Print(MQLInfoInteger(MQL_MEMORY_USED)); // 0
    
      ArrayFree(Ticks);
      Print(MQLInfoInteger(MQL_MEMORY_USED)); // 0

 
Renat Fatkhullin #:

Потому, что массив физически перестраивается и переносится в новую память.

Так зачем физически перестраивать при понижении размерности? Нужно же только счетчик количества элементов массива уменьшить!