Быстрый TimeHour/TimeMinute? - страница 3

 
Выдрал отсюда.
int TimeHour( const datetime dt ) { return(((int)dt / 3600) % 24); }
int TimeMinute( const datetime dt ) { return(((int)dt / 60) % 60); }
int Hour() { return(TimeHour(TimeCurrent())); }
int Minute() { return(TimeMinute(TimeCurrent())); }
 

Вот так будет без вариантов для оптимизации компилятора.

#define size 1000000

void  OnStart() {
   datetime T[size];
   for(int i=0; i<size; i++) T[i]=datetime(ulong(rand()&7)<<30|ulong(rand())<<15|rand());
   ulong sumM=0,sumH=0,_sumM=0,_sumH=0;
   ulong s1 = GetMicrosecondCount();
   for(int i=0; i<size; i++) sumH+=TimeHour(T[i]);
   ulong s2 = GetMicrosecondCount();
   for(int i=0; i<size; i++) sumM+=TimeMinute(T[i]);
   ulong s3 = GetMicrosecondCount();
   for(int i=0; i<size; i++) _sumH+=TimeHourMy(T[i]);
   ulong s4 = GetMicrosecondCount();
   for(int i=0; i<size; i++) _sumM+=TimeMinuteMy(T[i]);
   ulong s5 = GetMicrosecondCount();
   Print("Время выполнения одной итерации:");
   Print( "TimeHour:     ", (s2-s1)/1000.0, " ns, Контрольная сумма: - ",sumH );
   Print( "TimeHourMy:   ", (s4-s3)/1000.0, " ns, Контрольная сумма: - ",_sumH );
   Print( "TimeMinute:   ", (s3-s2)/1000.0, " ns, Контрольная сумма: - ",sumM );
   Print( "TimeMinuteMy: ", (s5-s4)/1000.0, " ns, Контрольная сумма: - ",_sumM );
}

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

int TimeHour(datetime time) {
   MqlDateTime tm;
   TimeToStruct(time,tm);
   return(tm.hour);
}
int TimeMinute(datetime time) {
   MqlDateTime tm;
   TimeToStruct(time,tm);
   return(tm.min);
}

//+------------------------------------------------------------------+
int TimeHourMy  ( const datetime dt ) { return int(((ulong)dt / 3600) % 24); }
int TimeMinuteMy( const datetime dt ) { return int(((ulong)dt / 60)   % 60); }
//+------------------------------------------------------------------+


В результате получаем объективную ожидаемую картину.
Выйгрыш где-то на 2 порядка...
с учетом того, что в иттерацию входит кроме времени выполнения самой функции, время доступа к i элементу массива, ulong сумма, инкремент i и проверка на выход из диапазона

2019.11.15 15:28:06.247 TestTimeMinute (USDRUB,M15)     Время выполнения одной итерации:
2019.11.15 15:28:06.247 TestTimeMinute (USDRUB,M15)     TimeHour:     45.082 ns, Контрольная сумма: - 11498816
2019.11.15 15:28:06.247 TestTimeMinute (USDRUB,M15)     TimeHourMy:   1.453 ns,  Контрольная сумма: - 11498816
2019.11.15 15:28:06.247 TestTimeMinute (USDRUB,M15)     TimeMinute:   43.735 ns, Контрольная сумма: - 29490375
2019.11.15 15:28:06.247 TestTimeMinute (USDRUB,M15)     TimeMinuteMy: 1.399 ns,  Контрольная сумма: - 29490375
т.е. реально получение часа или минуты из времени занимает меньше наносекунды, тогда как через структуру десятки наносекунд.
 

А вот и тяжелая артиллерия! )

Всем спасибо, протестирую и отпишусь.

 
Andrey Khatimlianskii:

А вот и тяжелая артиллерия! )

Всем спасибо, протестирую и отпишусь.

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

В тестере, на 48 млн вызовов обеих функций, получил ускорение около 25%.

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

Вывод: для универсальности и простоты, а также для одиночных вызовов, можно и нужно использовать функции отсюда или отсюда (не сравнивал int и ulong между собой), а для получения сразу нескольких составляющих времени, лучше объявить одну MqlDateTime структуру и сделать TimeToStruct.

Всех благодарю за участие!

 
Nikolai Semko:
самое сложное и интересное, это получить номер месяца из времени

Ты невыносимый перфекционист ))

Я озадачился ускорением из абсолютно практичных соображений — функция проверки рабочего времени (сложная и многофункциональная) занимала невыносимо много времени (до 20% всего времени теста). Раскопки указали, в том числе, на TimeHour с TimeMinute, вот и полез их оптимизировать.

А "из любви к искусству" лучше заняться чем-то более романтичным, чем вычисление номера месяца ;)

 
Andrey Khatimlianskii:

Ты невыносимый перфекционист ))

Я озадачился ускорением из абсолютно практичных соображений — функция проверки рабочего времени (сложная и многофункциональная) занимала невыносимо много времени (до 20% всего времени теста). Раскопки указали, в том числе, на TimeHour с TimeMinute, вот и полез их оптимизировать.

А "из любви к искусству" лучше заняться чем-то более романтичным, чем вычисление номера месяца ;)

Конечно же, ты прав, Андрей. 
Ох, нелегкая это работа - не отвлекаться на второстепенности... 

 
bool timeLimitHourTrade(
                         int startHourTrade
                        ,int endHourTrade){
   if(TimeHour(TimeLocal()) >= startHourTrade && TimeHour(TimeLocal()) < endHourTrade)  {
      return true;
   } else  {
      return false;
   }
}
 
Что делать, если я не могу найти функцию TimeHour() в MQL5?
 
Baruandreas #:
Что делать, если я не могу найти функцию TimeHour() в MQL5?

Использовать TimeToStruct(). Там получаете все сразу, не только час.

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