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

 
Alexandr Andreev:

Вы ничего не перепутали в своем коде, кто за вас будет значение 

изменять, как это происходит в первом варианте

Да, упустил этот момент. Исправил свой пост.

 
Valeriy Yastremskiy:

Там случайный результат. При компиляции разворачивается доступ к ячейке памяти со значением размера массива,  а размер массива будет получен и помещен в ячейку памяти заранее, при формировании массива, даже если массив динамический, и ячейки с размером массива и со значением переменной будут одинаковы по времени доступа.

Ну и судя по фразе, что компиляторы делают на 3-4 курсе информатики ... в общем буду надеяться что достаточно необходимый уровень кадров не даст мне сильно нервничать в среде МКЛ)

Поверьте средний студент обычно ФИВТа - это просто ноль с плюсом), т.к. опыта ноль, а знания без опыта быстро уходят в никуда (забываются), да и их примеры очень странные, пройдут года прежде чем студент поймет где и как их можно использовать. Это если сравнивать с бывалым программистом.

 
Alexandr Andreev:

Поверьте средний студент обычно ФИВТа - это просто ноль с плюсом), т.к. опыта ноль, а знания без опыта быстро уходят в никуда (забываются), да и их примеры очень странные, пройдут года прежде чем студент поймет где и как их можно использовать. Это если сравнивать с бывалым программистом.

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

 

Тема вообще про дефайны, а не про циклы ))

Мне всё же не понятно, есть ли смысл дефайнить код, например пользовательские функции.
В надежде что задефайненый код будет быстрее выполнятся в исполняемом файле.
Или это заблуждение? Так как подстановка это всего лишь пред компиляционное действие, и логично только для ускорения сборки.

 
Roman:

Тема вообще про дефайны, а не про циклы ))

Мне всё же не понятно, есть ли смысл дефайнить код, например пользовательские функции.
В надежде что задефайненый код будет быстрее выполнятся в исполняемом файле.
Или это заблуждение? Так как подстановка это всего лишь пред компиляционное действие, и логично только для ускорения сборки.

я же скинул пример где используется 3 внешние функции... против его развернутого вида. Т.е. ускорения не будет

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

вопрос к знатокам #define

Alexandr Andreev, 2020.11.02 19:49

void OnStart()
  {
   int mas[];
   int size=1000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100;
   uint t1=GetTickCount();
   int t=0;
   int tr=0; 
   MathSrand(10);
   for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); Funk(i))
        { 
         FunkRand(r1); 
         Funk(r);// мы сюда написали вызов еще одной функции чтобы усложить ситуацию
        }
     }
   tr=r;
   uint t2=GetTickCount();
   for(ulong z=0; z<max; z++)
     {
     int v=size;
      for(ulong i=0; i<v; i++)
        { 
         r2+=rand();
         r--;
        }

     }

   uint t3=GetTickCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",t1," ",tr);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

Вопрос на 500р (без проверки), какой способ быстрее. смотри сколько в верхнем методе вызывается всяких внешних функций


Документация по MQL5: Основы языка / Функции / Описание внешних функций
Документация по MQL5: Основы языка / Функции / Описание внешних функций
  • www.mql5.com
Внешние функции, определенные в другом модуле, должны быть явно описаны. Описание включает в себя тип возвращаемого значения, имя функции и набор входных параметров с их типами. Отсутствие такого описания может привести к ошибкам при компиляции, компоновке или выполнении программы. При описании внешнего объекта используйте ключевое слово С...
 
Alexandr Andreev:

я же скинул пример где используется 3 внешние функции... против его развернутого вида. Т.е. ускорения не будет


Понятно. Тогда привет fxsaber`у. Любителю всё подряд дефайнить.


Alexandr Andreev:

дак докажите мне обратное)

а то у меня в тесте почему-то они одинаковые

Что касается ArraySize() и переменной. Всё таки вернусь к этому вопросу.
Вот изменил тест. Цикл считает число PI.
В первом примере, в условии цикла используется ArraySize().
Во втором примере, используется переменная num_steps.
Разница есть.

Функция ArraySize()

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<ArraySize(arr); i++)
    {
       x = (i + .5) * step;
       sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Три запуска скрипта.

2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  Total time to calculate PI was 4049.179 ms
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  Total time to calculate PI was 4183.364 ms
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  Total time to calculate PI was 4034.098 ms
        


Переменная num_steps

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<num_steps; i++)
    {
        x = (i + .5) * step;
        sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Три запуска скрипта.

2020.11.03 00:08:09.269 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  Total time to calculate PI was 3955.325 ms
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  Total time to calculate PI was 3950.568 ms
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  Total time to calculate PI was 3927.110 ms
        
 
Roman:

Понятно. Тогда привет fxsaber`у. Любителю всё подряд дефайнить.

Что касается ArraySize() и переменной. Всё таки вернусь к этому вопросу.
Вот изменил тест. Цикл считает число PI.
В первом примере, в условии цикла используется ArraySize().
Во втором примере, используется переменная 
num_steps.
Разница есть.

Функция ArraySize()

Три запуска скрипта.


Переменная num_steps

Три запуска скрипта.

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

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

Функция ArraySize говорит чтобы компилятор вернул значение этой переменной т.е. он прям вместо этой функции подставляет эту переменную а т.к. масивы в мкл не могут равняться ссылкам, то указатель явный, явно на эту переменную, прям на крокетный адрес в памяти. Технически все эти тесты это попытка сравнить две обычных переменных. Это и есть свойство разворачивания функций, в моем примере 4 функции простив 0 функций, 3 из которых находиться прям в теле цикла т.е. там идет сравнения 40000000000 вызовов функций против ни одного. И мы видем неявную разницу которая слишком мала чтобы её заметить - т.к. это поставление кода в исполняемом файле.... мы сравниваем одно и тоже.

а все эти расчеты - чем они сложнее тем меньше от них смысла.

Проще привести пример где в одном случае будет вызываться сотня функций, функции в функциях... А в другом все это в развернутом виде  -  и разницы не будет. Т,к.  ArraySize(mas)== mas[].size

Документация по MQL5: Операции с массивами / ArraySize
Документация по MQL5: Операции с массивами / ArraySize
  • www.mql5.com
"Нулевое измерение = Размер массива / (Первое измерение * Второе измерение * Третье измерение)"
 

Хотя почему-то пример с пи разница всеж есть.....по частоте перевеса, (редация) хотя всеж это чисто случайный перевес

и она равна 1мс на 1 миллиард вывозов, хотя это не явно попробовал сравнить переменную с переменной дак разброс стал еще больше))


 
Alexandr Andreev:

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

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

Функция ArraySize говорит чтобы компилятор вернул значение этой переменной т.е. он прям вместо этой функции подставляет эту переменную а т.к. масивы в мкл не могут равняться ссылкам, то указатель явный, явно на эту переменную, прям на крокетный адрес в памяти. Технически все эти тесты это попытка сравнить две обычных переменных. Это и есть свойство разворачивания функций, в моем примере 4 функции простив 0 функций, 3 из которых находиться прям в теле цикла т.е. там идет сравнения 40000000000 вызовов функций против ни одного. И мы видем неявную разницу которая слишком мала чтобы её заметить - т.к. это поставление кода в исполняемом файле.... мы сравниваем одно и тоже.

а все эти расчеты - чем они сложнее тем меньше от них смысла.

Проще привести пример где в одном случае будет вызываться сотня функций, функции в функциях... А в другом все это в развернутом виде  -  и разницы не будет. Т,к.  ArraySize(mas)== mas[].size

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

Я не знаток ассемблера, но я думаю, что с точки зрения ассемблерных инструкций, это не одно и тоже.
А если это ещё и в классе обёрнуто, то тем более не одно и тоже.

Функция имеет лишнюю инструкцию для получения значения из ячейки памяти, то есть функция обращается к ячейке памяти за значением, и только потом возращает результат.
В переменной же уже есть это значение, переменная не куда не обращается, она сразу возвращает результат.

 
Roman:

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

Я не знаток ассемблера, но я думаю, что с точки зрения ассемблерных инструкций, это не одно и тоже.
А если это ещё и в классе обёрнуто, то тем более не одно и тоже.

Функция имеет лишнюю инструкцию для получения значения из ячейки памяти, то есть функция обращается к ячейке памяти за значением, и только потом возращает результат.
В переменной же уже есть это значение, переменная не куда не обращается, она сразу возвращает результат.

) ну это немного не так работает)

 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   int mas[];
   int mas1[300];
   int mas2[300];
   int mas3[300];
   int mas4[300];
   int mas5[300];
   int mas6[300];
   int z=300;
   int size=100000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100; 
   int t=0;
   int tr=0; 
   MathSrand(10);
    int num_steps=ArraySize(mas);
    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
     int v=size;
    ulong t1 = GetMicrosecondCount();
     
    
  // for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); i++)
        { 
        r2+=ArraySize(mas);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2=r2/10;
        }

     }  
   ulong t2=GetMicrosecondCount();
   //for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<v; i++)
        { 
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1=r1/10;
        }
     }
   
   int pi2 = sum*step;
   ulong t3=GetMicrosecondCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",pi," ",pi2);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

Почти каждый запуск лидер меняется

самое долгое тут это деление)))

Причина обращения: