вопрос к знатокам #define - страница 4

 
Alexandr Andreev:

Развертывание обычных функций - это само собой

т.е. к примеру for (int i=0; i<ArraiSize(max); i++)

тут  ArraiSize(max); разворачивается и там получается что то типо адреса на размер данного массива (если расматривать масив то у него есть в перемнной его размер, и вот тут проходит подстановка на эту переменную "адрес в памяти") т.е. нет смысла самому менять его на переменную, вообще.

 for (int i=0; i<ArraiSize(max); i++)

и

for (int i=0; i<size; i++) 

В данному случае  ArraiSize(max) и  size имеют одинаковые тайминги к определению значения размера массива

не правильное утверждение

протестировал: замер 1000 раз, 3 массива и 3 вложенных цикла перебора по каждому массиву, 2 варианта: 1-й и 2-й 

результат стабильно  (тестировал 3 раза):

2020.11.02 21:17:25.952 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=114.5013

2020.11.02 21:17:40.713 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=99.7722

обсуждать методику тестирования не вижу смысла - очень долго и нужно
 
Roman:

В этом примере цикла, наверно не соглашусь про тайминги.
Рекомендуют наоборот, получить результат в переменную size, и её уже использовать в условии.
Так как цикл на каждой итерации для ArraiSize(max), будет делать лишнее разворачивание, замедляя выполнение цикла.

Происходит раскрытие функции  ArraiSize(max) которая достает из массива ячейку с записью длины возвращает её, адрес ячейки где записана длина массива

а что такое любая переменная, в нашем случае size - это адрес ячейки где записана длина массива

т.е. на выходе получается одно и тоже и даже если мы в процессе цикла меняем как то размер массива, адрес на ячейку от этого не меняется ни в первом ни во втором случае.

А т.к. у нас значение mas всегда статично (это не ссылка) то тут другой логики просто не может быть)))

сама функция  ArraiSize(max), говорит что тут надо использовать участок памяти у массива max который отвечает за длину массива, причем это выполняется на этапе компилирования - развертывание функции

 
Igor Makanu:

не правильное утверждение

протестировал: замер 1000 раз, 3 массива и 3 вложенных цикла перебора по каждому массиву, 2 варианта: 1-й и 2-й 

результат стабильно  (тестировал 3 раза):

2020.11.02 21:17:25.952 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=114.5013

2020.11.02 21:17:40.713 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=99.7722

обсуждать методику тестирования не вижу смысла - очень долго и нужно

тогда какие-то проблемы со сборкой....

 
Alexandr Andreev:

тогда какие-то проблемы со сборкой....

Это понятно, что на выходе получается одно и тоже.
Вот только по разному будет доставаться этот участок памяти, про это и был смысл.
Обращение к переменной быстрее чем к функции, так как переменная уже содержит значение.
А функции нужно ещё получить это значение и вернуть, то есть сослаться на ячейку памяти, лишняя инструкция.

Пример Игоря, как раз подтверждение тому, о чём я говорил.

 
Alexandr Andreev:

тогда какие-то проблемы со сборкой....

врали

 вызов ArraySize() происходит на каждой итерации

даже если не происходит каждый раз контроль размера массива, то все равно происходит вызов процедуры и как минимум проверка переменной которая хранит значение размера массива

вот тест о  чем пишу, изменяем размер массива в цикле, цикл прервался как положено, т.е. на каждой итерации цикла размер массива определялся после исполнения тела цикла:

void OnStart()
{
   int arr[];
   int sz = ArrayResize(arr, 100000);
   int cnt = 0;
   for(int i = 0; i < ArraySize(arr); i++)
   {
      ArrayResize(arr, sz--);
      cnt++;
   }
   printf("cnt = %i", cnt);   //cnt = 50001
}
 
Igor Makanu:

врали

 вызов ArraySize() происходит на каждой итерации

даже если не происходит каждый раз контроль размера массива, то все равно происходит вызов процедуры и как минимум проверка переменной которая хранит значение размера массива

вот тест о  чем пишу, изменяем размер массива в цикле, цикл прервался как положено, т.е. на каждой итерации цикла размер массива определялся после исполнения тела цикла:

Давайте полный код своего теста

Roman:

Это понятно, что на выходе получается одно и тоже.
Вот только по разному будет доставаться этот участок памяти, про это и был смысл.

Пример Игоря, как раз подтверждение тому, о чём я говорил.

А вы сами тест проводили, у меня при 11000000000000000 чет-то нету такого

Точнее у меня вообще нет подобного ни при каких тестах, даже при LONG_MAX повторов
 
Alexandr Andreev:

Происходит раскрытие функции  ArraiSize(max) которая достает из массива ячейку с записью длины возвращает её, адрес ячейки где записана длина массива

а что такое любая переменная, в нашем случае size - это адрес ячейки где записана длина массива

т.е. на выходе получается одно и тоже и даже если мы в процессе цикла меняем как то размер массива, адрес на ячейку от этого не меняется ни в первом ни во втором случае.

А т.к. у нас значение mas всегда статично (это не ссылка) то тут другой логики просто не может быть)))

сама функция  ArraiSize(max), говорит что тут надо использовать участок памяти у массива max который отвечает за длину массива, причем это выполняется на этапе компилирования - развертывание функции

Это суждение представляется поспешным. Что именно происходит за фасадом функции  ArraiSize неизвестно, не так ли? В MQL это черный ящик. Вполне возможно, что  for (int i=0; i<ArraiSize(max); i++)  приведет к выполнению нескольких инструкций. Например, функция может проверить входные параметры. Сохранить - вытолкнуть данные из стека. Сохранить регистры. Восстановить регистры. Вызов функции - call, потом возврат. Я это к тому, что на заднем плане  может происходить очень много чего, причем мы увидеть этого не можем. Поэтому надежнее использовать for (int i=0; i<size; i++)  и не полагаться на то, что компилятор должен делать что - то, что мы предполагаем.

 
Alexandr Andreev:

А вы сами тест проводили, у меня при 11000000000000000 чет-то нету такого


Это уже давно было протестировано, по этому в циклах использую только переменные. 

 
Roman:

Это уже давно было протестировано, по этому в циклах использую только переменные. 

Покажите мне тест с кодом

 
Alexandr Andreev:

Покажите мне тест с кодом

Да какой тест?  ))
Вы сами показали оба варианта условия цикла.
Игорь выше тоже код привёл.
Просто замерьте выполнение цикла с переменной size и с ArraySize() в условии цикла.