Вопрос по особенности работы функции Print в скриптах.

 
Имеем простейший скрипт
//+------------------------------------------------------------------+
//|                                                   Test_Print.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   Print("Старт");
   for(int i=0;i<1000;i++) Print(i);
   Print("Стоп");
//----
   return(0);
  }
//+------------------------------------------------------------------+


Имеем результат его работы в логе:
2006.04.09 23:58:38 Test_Print EURUSDm,M1: removed
2006.04.09 23:58:38 Test_Print EURUSDm,M1: Стоп
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 999
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 998
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 997

********продолжение печати в правильном возрастании номеров********

2006.04.09 23:58:38 Test_Print EURUSDm,M1: 788
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 787
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 786
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 785
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 784
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 783
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 782
2006.04.09 23:58:38 Test_Print EURUSDm,M1: 781
2006.04.09 23:58:31 Compiling 'Test_Print'

Вопрос. Почему в лог не выводится печать номеров с 1 по 780? А также не выводится надпись “Старт”?

Если в цикл добавить паузу Sleep(100) то вывод в лог производится идеально как и задумано по программе. То есть выводится надпись “Старт” и вся последовательность номеров от 0 до 999.

//+------------------------------------------------------------------+
//|                                                   Test_Print.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   Print("Старт");
   for(int i=0;i<1000;i++) {Print(i); Sleep(100);}
   Print("Стоп");
//----
   return(0);
  }
//+------------------------------------------------------------------+



При этом у меня имеются подозрения, что такая непонятная особенность работы скриптов в МТ4 относится и к вызовам других функций. Кто-нибудь может мне показать как можно вывести значения через функцию Print без использования паузы? Пауза РЕЗКО замедляет работу всего скрипта!

 
Дело в том, что терминал достаточно умный, чтобы не тратить всю свою мощность на вывод сотен и тысяч строк в секунду в окно логов. Когда вывод в логи идет с огромной скоростью (сотни и тысячи строк в секунду), то терминал выводит в окно только часть данных.

Почему это делается? Потому что 100% вывод всех сообщений в окно(именно окно) логов - это абсолютно затратная операция. Если бы мы использовали прямой вывод каждой строки в лог непосредственно и сразу, то затраты распределились бы так: 0.1 сек на проход цикла в 1000 итераций + 5 сек на вывод в журнал, итогом будет 5.1 сек. А с использованием нашего метода экономного вывода мы практически не тормозим эксперта на выводе сообщений в окно, что позволяет нам уложиться итогово в 0.1 сек.

Если сообщения поступают в окно журнала помедленней (например, десяток сообщений в секунду), то все показывается нормально - такая частота поступления допустима.

Еще раз повторю: вывод в окно журнала урезается только (и только) для массированных логов, идущих со скоростью сотни и тысячи строк в секунду. И урезание касается исключительно окна просмотра. В файловый журнал все сообщения попадают без урезаний - это гарантируется 100%.

Проверьте файловые журналы с помощью команды "Открыть" из контекстного меню окна логов.
 
В качестве доказательства затратности отображения данных против их генерации я приведу пример этой же программы на языке C. Только цикл увеличен до 10000, чтобы заметить разницу. Программа консольная. Итак:
void main(void)
  {
   char  tmp[256];
   DWORD starttime=GetTickCount();
//----
   printf("Start\n");
   for(int i=0;i<10000;i++) 
     {
      sprintf(tmp,"%d\n",i);
      printf(tmp);
     }
   printf("Stop, %d ms used\n",GetTickCount()-starttime);
//----
  }


Результат запуска: "Stop, 421 ms used" - практически полсекунды потрачено на глупый цикл с непосредственным выводом результатов на экран. Причем результаты видны не все - только последние 300 строк, что по умолчанию помещаются в DOS окно.

Закомментарим строку printf(tmp) чтобы замерить скорость без вывода на экран. Результат: "Stop, 0 ms used". Как и следовало ожидать, время нулевое.

Теперь вернемся в МТ4 и его системе работы с визуализацией логов. Метатрейдер умудряется сделать всю работу и потратить на все это 32 ms.

Вот аналогичный код (цикл на 10000) на MQL4:

void start()
  {
   int starttime=GetTickCount();
//----
   Print("Start");
   for(int i=0;i<10000;i++) 
     {
      Print(i);
     }
   Print("Stop, ",GetTickCount()-starttime," ms used");
//----
  }



 
Renat, спасибо за подробнейший ответ! Действительно в самом файле журнала данные выводятся в полном объёме и без введения всяких пауз.
В связи с этим во избежание таких же повторных вопросов со стороны других пользователей хотелось бы чтобы данное обстоятельство было как-то отображено в справочной системе (например в описании функции Print). Поскольку для основной массы программистов-любителей, для которых программирование на MQL4 - это "вынужденное хобби" для работы на FOREX, данное обстоятельство совершенно не очевидно! Тем более, что вы специально наделили терминал функцией интеллекта, о которой без дополнительной информации догадаться проблематично.
 
было бы неплохо, если бы факт пропуска строк хотя бы фиксировался в журнале типа "some strings were omitted, see log-file"
а то так можно и чего-нибудь важное пропустить...
Причина обращения: