ArrayResize(), тем более на 1 элемент, крайне длительная операция, вы в основном его замеряли :-) Чтобы было шустро надо резервировать память, то есть использовать 3-й параметр
И смена порядка индексации - это всё-тами просто инверсия флага.
да ещё никто отчего-то не проверил корректность полученных данных :-) но это традиция
Максим, я взял то, что было предложено из учебника. И прекрасно понимаю, что в учебнике не самые оптимальные решения…
Мой посыл был направлен ТС для того, чтобы он обратил внимание на скорость копирования всей истории. И обратите внимание на то, что замер был в микросекундах. А в миллисекундах был 0…
ps; И пока не удалил код добавил в строку изменения размера массива
ArrayResize(p, n + 1, 10000);
Время сократилось почти в 3 раза
2024.01.2113:59:32.374 !!00 (USDJPY,M15) Первый замер 5480362024.01.2113:59:32.624 !!00 (USDJPY,M15) Второй замер 54802545662024.01.2113:59:41.336 !!00 (USDJPY,M15) Первый замер 5480352024.01.2113:59:41.586 !!00 (USDJPY,M15) Второй замер 54802531712024.01.2114:00:18.995 !!00 (USDJPY,M15) Первый замер 5480362024.01.2114:00:19.245 !!00 (USDJPY,M15) Второй замер 54802527242024.01.2114:00:25.393 !!00 (USDJPY,M15) Первый замер 5480352024.01.2114:00:25.643 !!00 (USDJPY,M15) Второй замер 54802548112024.01.2114:00:28.996 !!00 (USDJPY,M15) Первый замер 5480362024.01.2114:00:29.246 !!00 (USDJPY,M15) Второй замер 5480254185
но ни в какое сравнение не идёт с копированием всей истории.
Максим, я взял то, что было предложено из учебника. И прекрасно понимаю, что в учебнике не самые оптимальные решения…
Мой посыл был направлен ТС для того, чтобы он обратил внимание на скорость копирования всей истории. И обратите внимание на то, что замер был в микросекундах. А в миллисекундах был 0…
ps; И пока не удалил код добавил в строку изменения размера массива
Время сократилось почти в 3 раза
но ни в какое сравнение не идёт с копированием всей истории.
вывод неверный.
если вынести ArrayResize из второго цикла наружу - будут примерно похожие показания.
Вы измерили ArrayResize (это функция катастрофа), а результат интерпретируете к CopyRates
PS когда важна скорость, то заранее делать все массивы, чтобы как можно меньше обращаться к ArrayResize. Тогда можно обойтись без микрооптимизаций в стиле fxsaber (не натягивать наносекунды жертвуя читабельностью) ;-)
если вынести ArrayResize из второго цикла наружу - будут примерно похожие показания.
Вы измерили ArrayResize (это функция катастрофа), а результат интерпретируете к CopyRates
PS когда важна скорость, то заранее делать все массивы, чтобы как можно меньше обращаться к ArrayResize. Тогда можно обойтись без микрооптимизаций в стиле fxsaber (не натягивать наносекунды жертвуя читабельностью) ;-)
Согласен. Не сильно вникал и напрягал мозги.
i = 0;
MqlRates p[], r[];
start = GetMicrosecondCount();
int n = ArrayResize(p, Bars(_Symbol, PERIOD_CURRENT), 10000);
do
{
ArraySetAsSeries(p, true);
CopyRates(_Symbol, PERIOD_CURRENT, i, 1, r);
p[i] = r[0];
ArraySetAsSeries(p, false);
i++;
}
while(i < rates_total && !IsStopped());
Print("Второй замер ", rates_total, " ", GetMicrosecondCount()-start);
Но результат неутешительный
2024.01.2115:33:16.262 !!00 (USDJPY,M15) Первый замер 5480362024.01.2115:33:16.262 !!00 (USDJPY,M15) Второй замер 54807272024.01.2115:33:19.983 !!00 (USDJPY,M15) Первый замер 5480362024.01.2115:33:19.984 !!00 (USDJPY,M15) Второй замер 54807342024.01.2115:33:23.449 !!00 (USDJPY,M15) Первый замер 5480352024.01.2115:33:23.449 !!00 (USDJPY,M15) Второй замер 54807272024.01.2115:33:27.759 !!00 (USDJPY,M15) Первый замер 5480362024.01.2115:33:27.759 !!00 (USDJPY,M15) Второй замер 54807162024.01.2115:33:30.125 !!00 (USDJPY,M15) Первый замер 5480362024.01.2115:33:30.125 !!00 (USDJPY,M15) Второй замер 5480703
Вы что-то совсем не то между собой сравниваете. Вызывать в цикле копирование по одному бару - это полный идиотизм.
Напомню, что Было предложено вместо копирования всего массива котировок брать только свежие, как правило, один свежий бар (без всякого цикла).
Поэтому в замерах скорости нужно из второй части теста делить время на количество баров (будет ведь делаться только один запрос). Итого 716/5480 = 0.13, существенно лучше, чем ваши 36.
Вы что-то совсем не то между собой сравниваете. Вызывать в цикле копирование по одному бару - это полный идиотизм.
Напомню, что Было предложено вместо копирования всего массива котировок брать только свежие, как правило, один свежий бар (без всякого цикла).
Поэтому в замерах скорости нужно из второй части теста делить время на количество баров (будет ведь делаться только один запрос). Итого 716/5480 = 0.13, существенно лучше, чем ваши 36.
Совершенно верно. Возьмите одну итерацию цикла и полу́чите то, о чём вы говорите. Я сделал такие циклы, чтобы можно было сделать замер скорости выполнения не одной итерации, а многих…
В первом цикле было выполнено 5480 раз копирование всей истории, а во втором цикле 5480 раз по одному бару. И обратите внимание, на вопрос ТС и даже название темы
«Обновление массива Rates с каждым новым баров. Или как добавить в массив только последний бар.»
Поэтому если 36/5480 будет гораздо меньше чем 0,13… Почти в 20 раз.
Может вы не видели на первой странице весь код? Так мне не сложно повторить
/****************Custom indicator iteration function*****************/intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
//---if(prev_calculated > 0 && rates_total-prev_calculated > 1)
return0; // Если во время работы индикатора подгрузились новые бары, запустим пересчёт индикатора с нуля…//--- Основной цикл//--- Пересчитаем индикатор или от начала истории (от нулевого бара) или только последний барint i = 0;
MqlRates rates[];
ulong start = GetMicrosecondCount();
do
{
CopyRates(_Symbol, PERIOD_CURRENT, rates_total, 0, rates);
i++;
}
while(i < rates_total && !IsStopped());Print("Первый замер ", rates_total, " ", GetMicrosecondCount()-start);
//---
i = 0;
MqlRates p[], r[];
int n = ArrayResize(p, Bars(_Symbol, PERIOD_CURRENT), 10000);
start = GetMicrosecondCount();
do
{
ArraySetAsSeries(p, true);
CopyRates(_Symbol, PERIOD_CURRENT, i, 1, r);
p[i] = r[0];
ArraySetAsSeries(p, false);
i++;
}
while(i < rates_total && !IsStopped());Print("Второй замер ", rates_total, " ", GetMicrosecondCount()-start);
return(rates_total);
}/*******************************************************************/
Совершенно верно. Возьмите одну итерацию цикла и полу́чите то, о чём вы говорите. Я сделал такие циклы, чтобы можно было сделать замер скорости выполнения не одной итерации, а многих…
В первом цикле было выполнено 5480 раз копирование всей истории, а во втором цикле 5480 раз по одному бару. И обратите внимание, на вопрос ТС и даже название темы
«Обновление массива Rates с каждым новым баров. Или как добавить в массив только последний бар.»
Поэтому если 36/5480 будет гораздо меньше чем 0,13… Почти в 20 раз.
Может вы не видели на первой странице весь код? Так мне не сложно повторить
У вас оптимизация компиляции включена наверно? Тогда ваш первый цикл и вызов функции выполняется только 1 раз.
И красным и жирным шрифтом вы что хотели выделить? Я ответил именно на этот вопрос автора темы.
У вас оптимизация компиляции включена наверно? Тогда ваш первый цикл и вызов функции выполняется только 1 раз.
И красным и жирным шрифтом вы что хотели выделить? Я ответил именно на этот вопрос автора темы.
Не сильно изменилось.
2024.01.2117:57:37.051 !!00 (USDJPY,M15) Первый замер 5480742024.01.2117:57:37.051 !!00 (USDJPY,M15) Второй замер 54807642024.01.2117:57:53.619 !!00 (USDJPY,M15) Первый замер 5480822024.01.2117:57:53.619 !!00 (USDJPY,M15) Второй замер 548010352024.01.2118:00:33.448 !!00 (USDJPY,M15) Первый замер 5480892024.01.2118:00:33.448 !!00 (USDJPY,M15) Второй замер 548013102024.01.2118:00:38.762 !!00 (USDJPY,M15) Первый замер 5480842024.01.2118:00:38.762 !!00 (USDJPY,M15) Второй замер 5480904
Что касается выделенного красным: ТС хочет иметь всю историю для пересчёта на каждом баре. По этому ему нужен не только последний бар, а вся история. Или как минимум не один десяток баров. Вот и получается, либо на каждом баре копировать всю историю, либо копировать один бар и дописывать его в другой массив.
С каждым событием Calculate, вы заново физически выделяете память. Более того, терминал ее физически освобождает потом (с каждым Calculate).
Резервирование памяти (с помощью третьего параметра ArrayResize) не работает в вашем коде совсем. У вас один вызов ArrayResize, который с каждым Calculate заново выделяет память.
Весь этот do while можно заменить одним вызовом CopyRates, избежав копирования всех баров, а скопировав только те, которые были добавлены.
Вы ведь вызываете Bars() внутри ArrayResize. То есть, вам уже известно актуальное количество баров на графике. А количество баров, которые вы уже скопировали в глобальный массив на предыдущем OnCalculate будет равняться размеру этого глобального массива.
С каждым событием Calculate, вы заново физически выделяете память. Более того, терминал ее физически освобождает потом (с каждым Calculate).
Резервирование памяти (с помощью третьего параметра ArrayResize) не работает в вашем коде совсем. У вас один вызов ArrayResize, который с каждым Calculate заново выделяет память.
Весь этот do while можно заменить одним вызовом CopyRates, избежав копирования всех баров, а скопировав только те, которые были добавлены.
Вы ведь вызываете Bars() внутри ArrayResize. То есть, вам уже известно актуальное количество баров на графике. А количество баров, которые вы уже скопировали в глобальный массив на предыдущем OnCalculate будет равняться размеру этого глобального массива.
Изучите сначала тему с первого сообщения.
О каком выделении и освобождении памяти вы говорите, если в этом ПРИМЕРЕ выполнение цикла происходит только ОДИН раз. ТОЛЬКО ОДИН!!!
Не придирайтесь к словам. Смена порядка индексации это и есть переворачивание массива
ArrayResize(), тем более на 1 элемент, крайне длительная операция, вы в основном его замеряли :-) Чтобы было шустро надо резервировать память, то есть использовать 3-й параметр
И смена порядка индексации - это всё-тами просто инверсия флага.
да ещё никто отчего-то не проверил корректность полученных данных :-) но это традиция
Максим, я взял то, что было предложено из учебника. И прекрасно понимаю, что в учебнике не самые оптимальные решения…
Мой посыл был направлен ТС для того, чтобы он обратил внимание на скорость копирования всей истории. И обратите внимание на то, что замер был в микросекундах. А в миллисекундах был 0…
ps; И пока не удалил код добавил в строку изменения размера массива
Время сократилось почти в 3 раза
но ни в какое сравнение не идёт с копированием всей истории.
Максим, я взял то, что было предложено из учебника. И прекрасно понимаю, что в учебнике не самые оптимальные решения…
Мой посыл был направлен ТС для того, чтобы он обратил внимание на скорость копирования всей истории. И обратите внимание на то, что замер был в микросекундах. А в миллисекундах был 0…
ps; И пока не удалил код добавил в строку изменения размера массива
Время сократилось почти в 3 раза
но ни в какое сравнение не идёт с копированием всей истории.
вывод неверный.
если вынести ArrayResize из второго цикла наружу - будут примерно похожие показания.
Вы измерили ArrayResize (это функция катастрофа), а результат интерпретируете к CopyRates
PS когда важна скорость, то заранее делать все массивы, чтобы как можно меньше обращаться к ArrayResize. Тогда можно обойтись без микрооптимизаций в стиле fxsaber (не натягивать наносекунды жертвуя читабельностью) ;-)
вывод неверный.
если вынести ArrayResize из второго цикла наружу - будут примерно похожие показания.
Вы измерили ArrayResize (это функция катастрофа), а результат интерпретируете к CopyRates
PS когда важна скорость, то заранее делать все массивы, чтобы как можно меньше обращаться к ArrayResize. Тогда можно обойтись без микрооптимизаций в стиле fxsaber (не натягивать наносекунды жертвуя читабельностью) ;-)
Согласен. Не сильно вникал и напрягал мозги.
Но результат неутешительный
Согласен. Не сильно вникал и напрягал мозги.
Но результат неутешительный
Вы что-то совсем не то между собой сравниваете. Вызывать в цикле копирование по одному бару - это полный идиотизм.
Напомню, что Было предложено вместо копирования всего массива котировок брать только свежие, как правило, один свежий бар (без всякого цикла).
Поэтому в замерах скорости нужно из второй части теста делить время на количество баров (будет ведь делаться только один запрос). Итого 716/5480 = 0.13, существенно лучше, чем ваши 36.
Вы что-то совсем не то между собой сравниваете. Вызывать в цикле копирование по одному бару - это полный идиотизм.
Напомню, что Было предложено вместо копирования всего массива котировок брать только свежие, как правило, один свежий бар (без всякого цикла).
Поэтому в замерах скорости нужно из второй части теста делить время на количество баров (будет ведь делаться только один запрос). Итого 716/5480 = 0.13, существенно лучше, чем ваши 36.
Совершенно верно. Возьмите одну итерацию цикла и полу́чите то, о чём вы говорите. Я сделал такие циклы, чтобы можно было сделать замер скорости выполнения не одной итерации, а многих…
В первом цикле было выполнено 5480 раз копирование всей истории, а во втором цикле 5480 раз по одному бару. И обратите внимание, на вопрос ТС и даже название темы
«Обновление массива Rates с каждым новым баров. Или как добавить в массив только последний бар.»
Поэтому если 36/5480 будет гораздо меньше чем 0,13… Почти в 20 раз.
Может вы не видели на первой странице весь код? Так мне не сложно повторить
Совершенно верно. Возьмите одну итерацию цикла и полу́чите то, о чём вы говорите. Я сделал такие циклы, чтобы можно было сделать замер скорости выполнения не одной итерации, а многих…
В первом цикле было выполнено 5480 раз копирование всей истории, а во втором цикле 5480 раз по одному бару. И обратите внимание, на вопрос ТС и даже название темы
«Обновление массива Rates с каждым новым баров. Или как добавить в массив только последний бар.»
Поэтому если 36/5480 будет гораздо меньше чем 0,13… Почти в 20 раз.
Может вы не видели на первой странице весь код? Так мне не сложно повторить
У вас оптимизация компиляции включена наверно? Тогда ваш первый цикл и вызов функции выполняется только 1 раз.
И красным и жирным шрифтом вы что хотели выделить? Я ответил именно на этот вопрос автора темы.У вас оптимизация компиляции включена наверно? Тогда ваш первый цикл и вызов функции выполняется только 1 раз.
И красным и жирным шрифтом вы что хотели выделить? Я ответил именно на этот вопрос автора темы.Не сильно изменилось.
Что касается выделенного красным: ТС хочет иметь всю историю для пересчёта на каждом баре. По этому ему нужен не только последний бар, а вся история. Или как минимум не один десяток баров. Вот и получается, либо на каждом баре копировать всю историю, либо копировать один бар и дописывать его в другой массив.
У вас массивы p и r в локальной области.
С каждым событием Calculate, вы заново физически выделяете память. Более того, терминал ее физически освобождает потом (с каждым Calculate).
Резервирование памяти (с помощью третьего параметра ArrayResize) не работает в вашем коде совсем. У вас один вызов ArrayResize, который с каждым Calculate заново выделяет память.
Весь этот do while можно заменить одним вызовом CopyRates, избежав копирования всех баров, а скопировав только те, которые были добавлены.
Вы ведь вызываете Bars() внутри ArrayResize. То есть, вам уже известно актуальное количество баров на графике. А количество баров, которые вы уже скопировали в глобальный массив на предыдущем OnCalculate будет равняться размеру этого глобального массива.
У вас массивы p и r в локальной области.
С каждым событием Calculate, вы заново физически выделяете память. Более того, терминал ее физически освобождает потом (с каждым Calculate).
Резервирование памяти (с помощью третьего параметра ArrayResize) не работает в вашем коде совсем. У вас один вызов ArrayResize, который с каждым Calculate заново выделяет память.
Весь этот do while можно заменить одним вызовом CopyRates, избежав копирования всех баров, а скопировав только те, которые были добавлены.
Вы ведь вызываете Bars() внутри ArrayResize. То есть, вам уже известно актуальное количество баров на графике. А количество баров, которые вы уже скопировали в глобальный массив на предыдущем OnCalculate будет равняться размеру этого глобального массива.
Изучите сначала тему с первого сообщения.
О каком выделении и освобождении памяти вы говорите, если в этом ПРИМЕРЕ выполнение цикла происходит только ОДИН раз. ТОЛЬКО ОДИН!!!