Новая версия платформы MetaTrader 5 build 2007: Экономический календарь, MQL5-программы в виде сервисов - страница 34

 
Alexey Viktorov:
Так и глазам приятней. Если цикл растянут на пару страниц по высоте монитора, то замучаешься искать где он заканчивается, а свернуть нет возможности. Вот такими методами и выкручиваемся. А оказывается ещё и компилируется пошустрей. Приятно.

Вот возможности свернуть цикл крайне не хватает в ME - это правда!

 
Aleksey Vyazmikin:

Вот возможности свернуть цикл крайне не хватает в ME - это правда!

+1.

 
Alexey Kozitsyn:

+1.

Фолдинг народ просит уже больше 5 лет... Но R и Python для 2х человек важнее....

 

Код вызывает ошибку доступа к памяти в обоих терминалах (вылет по Access violation):

#property  strict

#define ARRAY_RESERVE_SIZE 100

struct MyStruct
{
   datetime dtTime;
   double   fPrice;   
   MyStruct(const datetime _dtTime = 0, const double _fPrice = 0.0)
   {
      dtTime = _dtTime;
      fPrice = _fPrice;
   }
};

MyStruct g_arrstStruct[];

//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Добавление нового элемента в массив                                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
template<typename T>
bool AddElementToArray(T& arrT[], const T& tElement)
{
   int nTotal = ArraySize(arrT);
   if (ArrayResize(arrT, nTotal + 1, ARRAY_RESERVE_SIZE) != nTotal + 1)
   {
      Alert(MQLInfoString(MQL_PROGRAM_NAME), ": error while adding the element to array of ", typename(T), " type.");
      return false;
   }
   
   arrT[nTotal] = tElement;
   return true;
}

bool ProcessElement(MyStruct &stStruct)
{
   MyStruct stNewStruct;
   if (!AddElementToArray(g_arrstStruct, stNewStruct))
      return false;
   
   stStruct.dtTime = 0;
   return true;
} 

void OnStart()
{
   int nTotal = int(fmin(iBars(NULL, PERIOD_CURRENT), 100000));
   for (int i = 0; i < nTotal; ++i)
   {
      MyStruct stStruct(iTime(NULL, PERIOD_CURRENT, i), iClose(NULL, PERIOD_CURRENT, i));
      if (!AddElementToArray(g_arrstStruct, stStruct))
         return;
   }

   Alert("Добавлено ", nTotal, " элементов.");

   for (int k = 0; k < 50000; ++k)
      ProcessElement(g_arrstStruct[ArraySize(g_arrstStruct) - 1]);
      
   Alert("Успешно");
}

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

Продублировал сообщение в тему по МТ4.

 
Renat Fatkhullin:

Инлайн наоборот увеличивает объем анализируемой портянки, так как встраиваемая функция полностью переносится в тело вызывающего блока.

У нас агрессивный инлайнинг ради ускорения. Без инлайнинга вообще об оптимизаторе кода говорить нельзя.

Renat Fatkhullin:

Нарежьте функции на множество более мелких и сократите время компиляции в разы и десятки раз.

Все время тратится на многопроходную оптимизацию портянки инструкций. Если делать длинные функции, то лапша вашего кода получается такой, что каждый проход оптимизации дает улучшение. Это приводит к множеству проходов оптимизатора кода.

Резать на мелкие, что все равно инлайнится, странно.

 
Ihor Herasko:

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

По коду не увидел криминала. Поясните, пожалуйста.

 
Aleksey Vyazmikin:

Да не, это просто база разных комбинаций листов дерева.

Что то типа такого:

Таких строк порядка 43к, ну и доп логика ещё на 2к строк (не считая дополнительных классов). Не знаю, почему так долго и нормально ли это...

Ну все, пора метаквотам думать о раздельной компиляции ))

 
Renat Fatkhullin:

Инлайн наоборот увеличивает объем анализируемой портянки, так как встраиваемая функция полностью переносится в тело вызывающего блока.

У нас агрессивный инлайнинг ради ускорения. Без инлайнинга вообще об оптимизаторе кода говорить нельзя.

А тут народ не в курсах насчет прологов-эпилогов функций ) Как у вас не могу знать, могу только у VS CPP посмотреть asm, на коротких функциях приличный оверхед 

 
fxsaber:

Резать на мелкие, что все равно инлайнится, странно.

Не странно. Вы просто не задумываетесь, какие портянки пишут некоторые люди.

Резать многотысячно строковые функции на более мелкие - это правильно. Я же не говорю резать на микрофункции по 5-10 строк.


Это общая проблема оптимизирующих компиляторов.

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

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

 
Aleksey Vyazmikin:

Спасибо! Действительно, так компилируется более чем в 10 раз быстрее. А на скорости исполнения кода это не отразится негативно?

Отобразится в лучшую сторону.
Причина обращения: