Вопрос к разработчикам - как сделать виртуальный буфер в индикаторе ? - страница 5

 
Integer:
Что то у вас не то там. Сейчас попробовал массив 10000000 - в момент отмасштабировался.

Я не знаю, у кого вообще тормозят ресайзы. Вот первые и последние 10 тысяч (1-10000 и 140000-150000) из 150 000 ресайзов, время на них, как видно, от длины массива никак не зависит, ни параболически, никак по-другому. На первых 7-10 тысячах видно, что время на resize вообще тратится не каждый раз, что подтверждает тезис о том, что память выделяется блоками по несколько элементов.

По оси ординат время в миллисекундах, уходящее на ресайз восьми буферов, скрипт ниже. Ни о каких подвисаниях на 30 секунд, описанных выше очевидцами, речи нет и в помине.



int start()
  {
//----
   double Buffer1[];
   double Buffer2[];
   double Buffer3[];
   double Buffer4[];
   double Buffer5[];
   double Buffer6[];
   double Buffer7[];
   double Buffer8[];
   ArrayResize(Buffer1,0);
   ArrayResize(Buffer2,0);
   ArrayResize(Buffer3,0);
   ArrayResize(Buffer4,0);
   ArrayResize(Buffer5,0);
   ArrayResize(Buffer6,0);
   ArrayResize(Buffer7,0);
   ArrayResize(Buffer8,0);
   
   int h = FileOpen("arrayresize.csv",FILE_CSV|FILE_WRITE);
   
   int i,t;
   
   for(i=1;i<150000;i++)
   {
      
      t=GetTickCount();

      ArrayResize(Buffer1,i);
      ArrayResize(Buffer2,i);
      ArrayResize(Buffer3,i);
      ArrayResize(Buffer4,i);
      ArrayResize(Buffer5,i);
      ArrayResize(Buffer6,i);
      ArrayResize(Buffer7,i);
      ArrayResize(Buffer8,i);
      Buffer1[i-1]=EMPTY_VALUE;
      Buffer2[i-1]=EMPTY_VALUE;
      Buffer3[i-1]=EMPTY_VALUE;
      Buffer4[i-1]=EMPTY_VALUE;
      Buffer5[i-1]=EMPTY_VALUE;
      Buffer6[i-1]=EMPTY_VALUE;
      Buffer7[i-1]=EMPTY_VALUE;
      Buffer8[i-1]=EMPTY_VALUE;

      t=GetTickCount()-t;
      
      FileWrite(h,t);
   }
   
   FileClose(h);

//----
   return(0);
  }
//+------------------------------------------------------------------+
 
alsu:

от длины массива никак не зависит

Поправлюсь: растет такими вот "уплотняющимися" ступеньками по 15-16 миллисекунд через каждые 10000-20000 шагов. Например, постепенное уплотнение видно на 1 графике.

Объяснить явление пока затрудняюсь.

 
alsu:

Я не знаю, у кого вообще тормозят ресайзы. Вот первые и последние 10 тысяч (1-10000 и 140000-150000) из 150 000 ресайзов, время на них, как видно, от длины массива никак не зависит, ни параболически, никак по-другому. На первых 7-20 тысячах видно, что время на resize вообще тратится не каждый раз, что подтверждает тезис о том, что память выделяется блоками по несколько элементов.

По оси ординат время в миллисекундах, уходящее на ресайз восьми буферов, скрипт ниже. Ни о каких подвисаниях на 30 секунд, описанных выше очевидцами, речи нет и в помине.




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

Если SetAsSerias() туда сюда и ресайз на один бар на каждом новом баре, то у меня тормозит (тестировать и оптимизировать не реально), и не только у меня так, однако некоторые утверждают что ничего не тормозит - вот что интересно.
Помнится с кем-то спорил (и проспорил)) насчет этого. Вопрос в том, с какой стороны приписываются новые элементы к массиву. Оказывается к series==false с правильно стороны (т.е. с конца), а к series==true почему-то тоже со стороны бОльших индексов (т.е. в начало! массива), что странно, ведь направление индексирования это всего лишь логический способ представления. Вполне возможно, что тут где-то происходит перебрасыание данных в памяти, из-за чего возможны тормоза.
 
alsu: Вот первые и последние 10 тысяч (1-10000 и 140000-150000) из 150 000 ресайзов, время на них, как видно, от длины массива никак не зависит, ни параболически, никак по-другому.

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

Но у меня ресайзы были массовыми, а тут они единичные. Конечно, все иначе.

Да и исследовал я до больших размеров, кстати. Вот и посмотри, что будет при размере буфера в несколько миллионов (грубо говоря, 3 года - миллион баров на М1).

 
Integer:
Что то у вас не то там. Сейчас попробовал массив 10000000 - в момент отмасштабировался.


Да вы правы, наверно какая то ошибка была.

Провел небольшой эксперимент с виртуальными буферами, возможно заинтересовавшимся темой будет интересно. Тут ArrayResize будет вызываться, не на каждом новом баре, а через определенный промежуток sizeStep. Так же iMAOnArray работает корректно, если ей не пользоваться можно вообще избежать установки буферов как серий. Этот индикатор в точности повторяет мой индикатор mabyma. Если будете сравнивать, обратившие внимание что в прикрепленном файле используется простое скользящее средние, а в mabyma подефолту ленейно взвешенное.

#property indicator_buffers 2
#property indicator_chart_window
#property indicator_color1 Green
#property indicator_color2 Red
#property indicator_level1 0

#define size     10000
#define sizeStep 10000
double SignalBuffer1[size];
double SignalBuffer2[size];
double SignalBuffer3[size];
double SignalBuffer4[size];
double SignalBuffer5[size];
double SignalBuffer6[size];
double SignalBuffer7[size];
double SignalBuffer8[size];
double SignalBuffer9[size];

double lineBuffer1[];
double lineBuffer2[];

int period1 = 100;
int period2 = 15;

int i;
int init(){
   SetIndexBuffer(0, lineBuffer1);
   SetIndexBuffer(1, lineBuffer2);
   IndicatorDigits(Digits + 1);

   ArraySetAsSeries(SignalBuffer1, true);
   ArraySetAsSeries(SignalBuffer2, true);
   ArraySetAsSeries(SignalBuffer3, true);
   ArraySetAsSeries(SignalBuffer4, true);
   ArraySetAsSeries(SignalBuffer5, true);
   ArraySetAsSeries(SignalBuffer6, true);
   ArraySetAsSeries(SignalBuffer7, true);
   ArraySetAsSeries(SignalBuffer8, true);
   ArraySetAsSeries(SignalBuffer9, true);

   ArrayInitialize(SignalBuffer1, 0);
   ArrayInitialize(SignalBuffer2, 0);
   ArrayInitialize(SignalBuffer3, 0);
   ArrayInitialize(SignalBuffer4, 0);
   ArrayInitialize(SignalBuffer5, 0);
   ArrayInitialize(SignalBuffer6, 0);
   ArrayInitialize(SignalBuffer7, 0);
   ArrayInitialize(SignalBuffer8, 0);
   ArrayInitialize(SignalBuffer9, 0);
}

int start(){
   
   int sizeNow = ArraySize(SignalBuffer1);
   if(sizeNow < Bars) {
      int step = sizeStep;
      if(Bars - sizeNow > step) {
         step = Bars - sizeNow + step;
      }
      resize(sizeNow + step);
   }
   
   
   int counted_bars =  IndicatorCounted();
   if(counted_bars>0) {
      counted_bars--;
   }
   int limit = Bars - counted_bars - 1;
   for(i = limit; i >= 0; i--) {
       setManualBuffer(SignalBuffer1, iMA(NULL, 0, period1, 0, 0, 0, i), i);       
   }
   for(i = limit; i >= 0; i--) {
       setManualBuffer(SignalBuffer2, iMAOnArray(SignalBuffer1, 0, period2, 0, 0, Bars - i - period2), i);   
   }
   for(i = limit; i >= 0; i--) {
       lineBuffer1[i]= getManualBuffer(SignalBuffer1, i);
       lineBuffer2[i]= getManualBuffer(SignalBuffer2, i);     
   }
}

void resize(int newSize) {

   ArraySetAsSeries(SignalBuffer1, false);
   ArraySetAsSeries(SignalBuffer2, false);
   ArraySetAsSeries(SignalBuffer3, false);
   ArraySetAsSeries(SignalBuffer4, false);
   ArraySetAsSeries(SignalBuffer5, false);
   ArraySetAsSeries(SignalBuffer6, false);
   ArraySetAsSeries(SignalBuffer7, false);
   ArraySetAsSeries(SignalBuffer8, false);
   ArraySetAsSeries(SignalBuffer9, false);
 
   ArrayResize(SignalBuffer1, newSize);
   ArrayResize(SignalBuffer2, newSize);  
   ArrayResize(SignalBuffer3, newSize);  
   ArrayResize(SignalBuffer4, newSize);  
   ArrayResize(SignalBuffer5, newSize);  
   ArrayResize(SignalBuffer6, newSize);  
   ArrayResize(SignalBuffer7, newSize); 
   ArrayResize(SignalBuffer8, newSize);
   ArrayResize(SignalBuffer9, newSize);

   ArraySetAsSeries(SignalBuffer1, true);
   ArraySetAsSeries(SignalBuffer2, true);
   ArraySetAsSeries(SignalBuffer3, true);
   ArraySetAsSeries(SignalBuffer4, true);
   ArraySetAsSeries(SignalBuffer5, true);
   ArraySetAsSeries(SignalBuffer6, true);
   ArraySetAsSeries(SignalBuffer7, true);
   ArraySetAsSeries(SignalBuffer8, true);
   ArraySetAsSeries(SignalBuffer9, true); 
 
}

bool setManualBuffer(double &buffer[], double value, int shift) {
   buffer[Bars - 1 - shift] = value;
}

double getManualBuffer(double &buffer[], int shift) {
   return(buffer[Bars - 1 - shift]);
}
Файлы:
test_2.mq4  4 kb
 
Mathemat:

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

Но у меня ресайзы были массовыми, а тут они единичные. Конечно, все иначе.

Да и исследовал я до больших размеров, кстати. Вот и посмотри, что будет при размере буфера в несколько миллионов (грубо говоря, 3 года - миллион баров на М1).

Подозреваю, что рост все таки будет. Но мне кажется все таки, что, здесь не все так просто... посмотрим.
 

От миллиона до 1001000 в пределах 100 миллисекунд на операцию

Поставил 10 миллионов - скрипт залез в подкачку (оперативы в машине 1ГБ), попутно выпихав туда все запущенные в системе программы, и завис почти намертво. Короче ждать я не стал.

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

 
alsu:

оперативы в машине 1ГБ

Несерьезно. Надо 3. А лучше 64-бит и 8 )).
4 гига ддр3 стоят уже 800 рублей
а 2 x 4 гига 1000...

 
jartmailru:

Несерьезно. Надо 3. А лучше 64-бит и 8 )).
4 гига ддр3 стоят уже 800 рублей
а 2 x 4 гига 1000...


Как пойдет на трейдинге с первого профита купим =)
Причина обращения: