В любом случае, вызов из библиотек будет медленнее MQL4 кода, подключенного через #include.
Первый вызов функции из внешней библиотеки требует загрузки и инициализации этой библиотеки практически как вызов из DLL. Это занимает существенное время. Последующие вызовы уже будут работать быстро. Попробуйте провести замеры, отбросив первый вызов.
В любом случае, вызов из библиотек будет медленнее MQL4 кода, подключенного
через #include.
А вы можете дать какую-нибудь оценку хотя бы порядка этого отличия? Просто 13 мс и 0 мс это серьезная разница.
Просто хочется окончательно решить, использовать ex4-библиотеки или нет. Уж слишком серьезный удар они могут оказать по скорости оптимизации в случае, если такая разница обусловлена их технической реализацией.
А вы можете дать какую-нибудь оценку хотя бы порядка этого отличия? Просто 13 мс и 0 мс это серьезная разница.
В любом случае, если Вы задумываетесь о скорости, то обязательно используйте включение полного исходного кода через #include "xxxxxx. mq4".
13 мс - это все в пределах погрешности системного таймера, нельзя на этом основании делать выводы. Перейдите за пределы 1000 мс и тогда выводы будут верные.
В любом случае, если Вы задумываетесь о скорости, то обязательно используйте включение полного исходного кода через #include "xxxxxx. mq4".
Спасибо за совет, будем иметь в виду.Тестовая функция в виде отдельной библиотеки (должна лежать в каталоге /libraries):
//+------------------------------------------------------------------+ //| externalfunc.mq4 | //| Copyright © 2007, MetaQuotes Software Corp. | //| https://www.metaquotes.net/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2007, MetaQuotes Software Corp." #property link "https://www.metaquotes.net/" #property library //+------------------------------------------------------------------+ //| Тестовая функция | //+------------------------------------------------------------------+ int ExternalFunc(int val1,int val2) { return(val1+val2); } //+------------------------------------------------------------------+Тестовый скрипт, совмещающий в себе тестирование обоих случаев:
//+------------------------------------------------------------------+ //| testfunctions.mq4 | //| Copyright © 2007, MetaQuotes Software Corp. | //| https://www.metaquotes.net// | //+------------------------------------------------------------------+ #property copyright "Copyright © 2007, MetaQuotes Software Corp." #property link "https://www.metaquotes.net//" //---- импортируем внешнюю функцию #import "externalfunc.ex4" int ExternalFunc(int val1,int val2); #import //+------------------------------------------------------------------+ //| Тестовая функция | //+------------------------------------------------------------------+ int InternalFunc(int val1,int val2) { return(val1+val2); } //+------------------------------------------------------------------+ //| Замеряем время собственный функции | //+------------------------------------------------------------------+ void TestInternalFunction() { //---- замерим время прокрутки в цикле int start=GetTickCount(); // засекаем время for(int i=0;i<10000000;i++) InternalFunc(i,i); // долгий цикл start=GetTickCount()-start; // определяем прошедшее время //---- распечатает результат Print("Internal function time: ",start," ms"); //---- return(0); } //+------------------------------------------------------------------+ //| Замеряем время внешней функции | //+------------------------------------------------------------------+ void TestExternalFunction() { //---- замерим время выполнения первого вызова int start=GetTickCount(); // засекаем время ExternalFunc(1,1); // однократный вызов start=GetTickCount()-start; // определяем прошедшее время //---- распечатает результат Print("External function time: ",start," ms (init)"); //---- замерим время прокрутки в цикле start=GetTickCount(); // засекаем время for(int i=0;i<10000000;i++) ExternalFunc(i,i); // долгий цикл start=GetTickCount()-start; // определяем прошедшее время //---- распечатает результат Print("External function time: ",start," ms"); //---- return(0); } //+------------------------------------------------------------------+ //| Замеры | //+------------------------------------------------------------------+ int start() { //---- TestInternalFunction(); TestExternalFunction(); //---- return(0); } //+------------------------------------------------------------------+
Вот результаты:
Internal function time: 1547 ms External function time: 0 ms (init) External function time: 2640 msПерейдя к бОльшим по времени расчетам (более 1000 ms вместо 0 ms и 13 ms), результаты стали достоверными и на них не влияет погрешность таймера. Какой можно сделать вывод?
Время вызова функции из библиотеки на 70% медленнее вызова внутри своего модуля.
Я специально отметил, что речь идет именно о потерях во времени вызова, а не о том, что любая функция из библиотеки на 70% медленнее родной. Сама функция в библиотеке
отрабатывается с той же скоростью, как и в родном модуле. Потеря
происходит только на межмодульном вызове.
Перейдя к бОльшим по времени расчетам (более 1000 ms вместо 0 ms и 13 ms), результаты стали достоверными и на них не влияет погрешность таймера. Какой можно сделать вывод?
Ну я же писал, что 0 и 13 мс это среднее время, вычисленное по результатам замеров общей длительностью около 27000 мс.
Но в любом случае спасибо за подтверждение. Т.о. небольшие часто используемые функции действительно лучше выносить в заголовочные файлы. Единственное неудобство - это предупреждения компилятора о том, что такие функции не используются. Они загромождают отчет об ошибках и лишний раз отвлекают внимание, когда таких функций много.
Единственное неудобство - это предупреждения компилятора о том, что такие функции не используются. Они загромождают отчет об ошибках и лишний раз отвлекают внимание, когда таких функций много.
#property libraryТем самым компилятор перестанет контролировать неиспользуемые функции. Все будет работать нормально.
Отлично. Спасибо за совет.
Кстати, использование "#property library" имеет один, но очень убийственный эффект для экспертов - пропадают все параметры, объявленные как "extern". Поэтому такой финт для подавления предупреждений компилятора использовать для экспертов в общем случае нельзя.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Просто сегодня столкнулся с забавной ситуацией. Имеется простейшая функция, реализация которой вынесена в отдельную библиотеку. Вызов этой функции из эксперта занимает по времени около 13 мс (расчитано как общее время потраченное на 2000 вызовов функции деленное на число вызовов). Это удивительно много!
Если эксперт анализирует последние 1000 баров, вызывая по одному разу эту функцию для каждого бара, то анализ этих 1000 баров занимает 13 секунд!
При этом, если я беру эту функцию и вставляю ее прямо в код эксперта, то среднее время, уходящее на вызов этой функции падает ниже пределов погрешности измерений.
Неужели вызовы библиотечных функций имеют такой overhead? Или я наткнулся на некоторый глюк?