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

 
Aleksandr Slavskii #:
Вторая и третья это по сути одно и то же.

Только если нас не волнует порядок перебора, а это не всегда так.

Aleksandr Slavskii #:
А вот первый вариант нужно использовать только если в цикле, может  изменяться размер массива.

Т.е., компилятор оптимизацию через добавочную переменную не делает.

 
JRandomTrader #:

Только если нас не волнует порядок перебора, а это не всегда так.

Я написал "по сути", а  направление перебора это уже частности.

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

JRandomTrader #:

Только если нас не волнует порядок перебора, а это не всегда так.

Т.е., компилятор оптимизацию через добавочную переменную не делает.

Точно не делает если в цикле есть функции, которые могут изменить размер массива. А вот насчёт циклов где таких функций нет, я не уверен, делает добавочную переменную или нет.

 
Aleksandr Slavskii #:
А вот насчёт циклов где таких функций нет, я не уверен, делает добавочную переменную или нет.

Вот именно это я и хотел узнать, но увы.

Никогда не знаешь, где лучше оптимизировать самому, а где - не мешать компилятору.

 
Aleksandr Slavskii #:
Судя по косвенным признакам компилятор смотрит размер массива на каждой итерации
И это правильно, если размер массива может измениться за время исполнения цикла.
 
   ObjectCreate(0, "OBJ_VLINE1", OBJ_VLINE, 0, TimeCurrent(), 0);
   ObjectCreate(0, "OBJ_VLINE2", OBJ_VLINE, 0, TimeCurrent(), 0);
   for (int i = 0; i < ObjectsTotal(); i++) {
      ObjectDelete(0, "OBJ_VLINE1");
      ObjectDelete(0, "OBJ_VLINE2");
      Print(i, " ", ObjectsTotal(), " name: ", ObjectName(0, i));
   }
   ObjectDelete(0, "OBJ_VLINE1");
   ObjectDelete(0, "OBJ_VLINE2");

// 0 0 name: 

Как компилятор (при оптимизации) узнает, что ObjectDelete повлияет на ObjectsTotal (и его не надо кэшировать)?

Только если метаквоты придумают магию.

 
fxsaber #:

Последнее время вы всё чаще стали применять такую конструкцию

for (uint i = Amount; (bool)i--;)

Как то попадалась тема с замерами скорости циклов, вы кстати тоже там вроде участвовали(но это не точно)

Так там выяснили, что for медленнее работает чем while

Вопрос: почему не 

uint i = Amount;
while((bool)i--)

или так

int i = Amount;
while(i-- > 0)

Вроде одно и тоже. Нет?

 
Aleksandr Slavskii #:

Как то попадалась тема с замерами скорости циклов

Оказалось, что компилятор создает иногда неэффективный код. Поэтому тестировать объективно различные варианты проблематично.


В этом коде можете оставлять одну из строк и смотреть на результат.

//    for (uint i = Amount; (bool)i--;)
//    for (int i = 0; i < Amount; i++)
//    for (int i = Amount - 1; i >= 0; i--)    
//    uint i = Amount; while((bool)i--)
    int i = Amount; while(i-- > 0)

Но из-за озвученного бага компилятора с выводами сложно. Более того, на машине один и тот же код может начать выполняться на 10% быстрее, а потом снова замедлиться. Все параллельные приложения убил, но все равно эффект присутствует.


Для себя пока оставил эту тему открытой.

 

b4242, ME по ALT+M показывает неверные значки.

class A
{
private:
  static void FuncStaticPrivate() {}
  void FuncPrivate() {}
  virtual void FuncVirtualPrivate() {}
  
public:
  static void FuncStaticPublic() {}
  void FuncPublic() {}
  virtual void FuncVirtualPublic() {}  
};


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

Юбилейная ошибка...

Строка для поискаOshibka 100.

 
fxsaber #:
//    for (uint i = Amount; (bool)i--;) //    for (int i = 0; i < Amount; i++) //    for (int i = Amount - 1; i >= 0; i--)     //    uint i = Amount; while((bool)i--)     int i = Amount; while(i-- > 0)
int i = Amount; while(i-- > 0)
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 95 in OnStart: GetSum(TicksArray)] = 1393745 mcs.
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 96 in OnStart: GetSum(TicksArray)] = 1304940 mcs.

uint i = Amount; while((bool)i--)
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 95 in OnStart: GetSum(TicksArray)] = 1324000 mcs.
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 96 in OnStart: GetSum(TicksArray)] = 1323747 mcs.

for (int i = Amount - 1; i >= 0; i--)
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 95 in OnStart: GetSum(TicksArray)] = 1234262 mcs.
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 96 in OnStart: GetSum(TicksArray)] = 1227259 mcs.

for (int i = 0; i < Amount; i++)
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 95 in OnStart: GetSum(TicksArray)] = 1234295 mcs.
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 96 in OnStart: GetSum(TicksArray)] = 1216125 mcs.

for (uint i = Amount; (bool)i--;)
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 95 in OnStart: GetSum(TicksArray)] = 1485159 mcs.
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 96 in OnStart: GetSum(TicksArray)] = 1345395 mcs.

int i = Amount; while(i > 0){i--;// код}
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 97 in OnStart: GetSum(TicksArray)] = 1321655 mcs.
Alert: Bench_Stack = 0, 1 <= Time[002.mq5 98 in OnStart: GetSum(TicksArray)] = 1296822 mcs.

В общем то вывод очевиден.

 
Aleksandr Slavskii #:

В общем то вывод очевиден.

Мне не очевиден, поскольку, сделав так, получите иные результаты.

  _B(GetSum(TicksArray), 1);
//  _B(GetSum(TicksArray), 1); // Замедляет выполнение предыдущей строки!
Причина обращения: