Array out of range - страница 4

 

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

Сравнительные результаты скорости выполнения выложить сюда.

Коды корректных скриптов выложить желающим видеть спец.директивы компилятора.

 
MetaDriver:
Вот именно.  И я бы предпочёл, чтоб данный сервис отключался директивами компилятора, когда программа уже отлажена и оттестирована.  Ибо на каждое обращение по индексу стопка проверок - это оченЪ дорого.
Данные проверки отключены не будут - это требования безопасности.
С отключёнными проверками можно ПРЕДНАМЕРЕННО сделать "промах" и использовать его в своих корыстных целях.

На данный момент оптимизатор убирает некоторые лишние проверки, например:

x=a[i];        // идёт проверка i на выход за пределы
y=a[i]*10;  // i не изменялся, размерность a не менялась - проверки на выход за пределы нет.


 
mql5:
Данные проверки отключены не будут - это требования безопасности.
С отключёнными проверками можно ПРЕДНАМЕРЕННО сделать "промах" и использовать его в своих корыстных целях.
Есть же галочка на использование DLL. Почему бы не добавить галочку на отключение защиты от дурака? И также, как с DLL, разрешать оптимизировать такие советники только на локальных агентах, без Cloud.
 
mql5:
Данные проверки отключены не будут - это требования безопасности.
С отключёнными проверками можно ПРЕДНАМЕРЕННО сделать "промах" и использовать его в своих корыстных целях.
О боже, ни один здаравомыслящий хакер на будет "вскрывать" исполняющую систему из под mql. Всегда можно получить физические адреса, используя системные (виндовские) DLL.  Примеры описаны в статьях на вашем же сайте.  Я рассматриваю данные проверки исключительно как ориентированные на  "честных" mql-программистов.   Типа щеколды на двери в туалет. Хорошего пинка всё равно не выдержит, но этого от неё и не требуется. Главное чтоб помогала в отладке и не крешила терминал. Всё.

На данный момент оптимизатор убирает некоторые лишние проверки, например:

x=a[i];        // идёт проверка i на выход за пределы
y=a[i]*10;  // i не изменялся, размерность a не менялась - проверки на выход за пределы нет.
Это уже очень хорошо, но на мой вкус недостаточно радикально.  Проверки реально массовые (и, думаю, часто чрезмерные), это хорошо чувствуется по тормознутости по сравнению с чистым нативным машинным кодом. 
 
hrenfx:
Есть же галочка на использование DLL. Почему бы не добавить галочку на отключение защиты от дурака? И также, как с DLL, разрешать оптимизировать такие советники только на локальных агентах, без Cloud.

+200

Вот реально хорошая идея. Разработчики, прошу обратить пристальное внимание!

--

Супер-быстродействие реально нужно именно в оптимизаторе, в остальных случаях быстродействия в подавляющем большинстве хватает.

// Не всегда, конечно. Быстродействия "много" не бывает. :) 

С другой стороны, я понимаю, что такой шаг понизит рейтинг облака (по сравнению с "местными" вычислениями), зато даст хороший стимул к оптимизации вашей защитной "паранойи".  Она таки хороша в меру.

 
MetaDriver:
О боже, ни один здаравомыслящий хакер на будет "вскрывать" исполняющую систему из под mql. Всегда можно получить физические адреса, используя системные (виндовские) DLL.  Примеры описаны в статьях на вашем же сайте.  Я рассматриваю данные проверки исключительно как ориентированные на  "честных" mql-программистов.   Типа щеколды на двери в туалет. Хорошего пинка всё равно не выдержит, но этого от неё и не требуется. Главное чтоб помогала в отладке и не крешила телминал. Всё.
Вы ошибаетесь, аргументировать свой ответ не буду, чтобы не вдаваться в подробности. К сожалению плата за безопасность - скорость.
 
MetaDriver:

Супер-быстродействие реально нужно именно в оптимизаторе, в остальных слачаях быстродействия в подавляющем большинстве хватает.

Повторная просьба к разработчиками показать, насколько замедляет защита от дурака. Если это десяток-другой процентов...

Также по теме оптимизаций в компиляторе:

Есть подозрение, что это не OpenCL крут, а отсутствие оптимизаций в самом MQL5.
 

         |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[]){
//--- we can copy not all data
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
   else
     {
      to_copy=rates_total-prev_calculated;
      if(prev_calculated>0) to_copy++;
     }
//---
   if(CopyTime(Symbol(), Period(), 0, to_copy, curTime)<=0){
      Print("Getting Time "+Symbol()+" is failed! Error ",GetLastError());
      return(0);
   }
   if(IsStopped()) return(0); //Checking for stop flag
   int i = ArraySize(curTime)-1; //Самая старая свеча в массиве дат
   if(CopyRates(InpSymbol1, Period(), curTime[0], curTime[i], tmpSymbol1)<=0){
      Print("Getting Rates "+InpSymbol1+" is failed! Error ",GetLastError());
      return(0);
   }
   if(IsStopped()) return(0); //Checking for stop flag
   if(CopyRates(InpSymbol2, Period(), curTime[0], curTime[i], tmpSymbol2)<=0){
      Print("Getting Rates "+InpSymbol2+" is failed! Error ",GetLastError());
      return(0);
   }
   if(IsStopped()) return(0); //Checking for stop flag
   if(CopyRates(InpSymbol3, Period(), curTime[0], curTime[i], tmpSymbol3)<=0){
      Print("Getting Rates "+InpSymbol3+" is failed! Error ",GetLastError());
      return(0);
   }
   if(IsStopped()) return(0); //Checking for stop flag
   if(CopyRates(InpSymbol4, Period(), curTime[0], curTime[i], tmpSymbol4)<=0){
      Print("Getting Rates "+InpSymbol4+" is failed! Error ",GetLastError());
      return(0);
   }
   if(IsStopped()) return(0); //Checking for stop flag
   if(CopyRates(InpSymbol5, Period(), curTime[0], curTime[i], tmpSymbol5)<=0){
      Print("Getting Rates "+InpSymbol5+" is failed! Error ",GetLastError());
      return(0);
   }
   if(IsStopped()) return(0); //Checking for stop flag
   if(CopyRates(InpSymbol6, Period(), curTime[0], curTime[i], tmpSymbol6)<=0){
      Print("Getting Rates "+InpSymbol6+" is failed! Error ",GetLastError());
      return(0);
   }
   if(IsStopped()) return(0); //Checking for stop flag
//--- Синхронизация исторических данных
   int limit;
   int j, k, z, x, f, h;
   if(prev_calculated==0)
      limit=0;
   else limit=prev_calculated-1;
   j=limit;
   k=limit;
   z=limit;
   x=limit;
   f=limit;
   h=limit;
   for(i=limit;i<rates_total && !IsStopped();i++){ //Движение от старой свечи к новой текущего графика
      if(j>=ArraySize(tmpSymbol1)) break;
      while(curTime[i]>tmpSymbol1[j].time && !IsStopped() && j<ArraySize(tmpSymbol1)-1){
         j++; //Дыра в истории текущего графика
      }
      if(k>=ArraySize(tmpSymbol2)) break;
      while(curTime[i]>tmpSymbol2[k].time && !IsStopped() && k<ArraySize(tmpSymbol2)-1){
         k++; //Дыра в истории текущего графика
      }
      if(z>=ArraySize(tmpSymbol3)) break;
      while(curTime[i]>tmpSymbol3[z].time && !IsStopped() && z<ArraySize(tmpSymbol3)-1){
         z++; //Дыра в истории текущего графика
      }
      if(x>=ArraySize(tmpSymbol4)) break;
      while(curTime[i]>tmpSymbol4[x].time && !IsStopped() && x<ArraySize(tmpSymbol4)-1){
         x++; //Дыра в истории текущего графика
      }
      if(f>=ArraySize(tmpSymbol5)) break;
      while(curTime[i]>tmpSymbol5[f].time && !IsStopped() && f<ArraySize(tmpSymbol5)-1){
         f++; //Дыра в истории текущего графика
      }
      if(h>=ArraySize(tmpSymbol6)) break;
      while(curTime[i]>tmpSymbol6[h].time && !IsStopped() && h<ArraySize(tmpSymbol6)-1){
         h++; //Дыра в истории текущего графика
      }
      
      
      if(curTime[i]<tmpSymbol1[j].time) {
         if(i>0) //Дыра в истории инструмента 1
            bufPrice1[i]=bufPrice1[i-1];
         else
            bufPrice1[i]=0;
      }else{
         bufPrice1[i]=CalcPrice(MA_Price, tmpSymbol1[j].open, tmpSymbol1[j].close, tmpSymbol1[j].high, tmpSymbol1[j].low);
      }
      
      
      if(curTime[i]<tmpSymbol2[k].time) {
         if(i>0) //Дыра в истории инструмента 2
            bufPrice2[i]=bufPrice2[i-1];
         else
            bufPrice2[i]=0;
      }else{
         bufPrice2[i]=CalcPrice(MA_Price, tmpSymbol2[k].open, tmpSymbol2[k].close, tmpSymbol2[k].high, tmpSymbol2[k].low);
      }
      
      
      if(curTime[i]<tmpSymbol3[z].time) {
         if(i>0) //Дыра в истории инструмента 3
            bufPrice3[i]=bufPrice3[i-1];
         else
            bufPrice3[i]=0;
      }else{
         bufPrice3[i]=CalcPrice(MA_Price, tmpSymbol3[z].open, tmpSymbol3[z].close, tmpSymbol3[z].high, tmpSymbol3[z].low);
      }
      
      
      if(curTime[i]<tmpSymbol4[x].time) {
         if(i>0) //Дыра в истории инструмента 4
            bufPrice4[i]=bufPrice4[i-1];
         else
            bufPrice4[i]=0;
      }else{
         bufPrice4[i]=CalcPrice(MA_Price, tmpSymbol4[x].open, tmpSymbol4[x].close, tmpSymbol4[x].high, tmpSymbol4[x].low);
      }
      
      
      if(curTime[i]<tmpSymbol5[f].time) {
         if(i>0) //Дыра в истории инструмента 5
            bufPrice5[i]=bufPrice5[i-1];
         else
            bufPrice5[i]=0;
      }else{
         bufPrice5[i]=CalcPrice(MA_Price, tmpSymbol5[f].open, tmpSymbol5[f].close, tmpSymbol5[f].high, tmpSymbol5[f].low);
      }
      
      
      if(curTime[i]<tmpSymbol6[h].time) {
         if(i>0) //Дыра в истории инструмента 6
            bufPrice6[i]=bufPrice6[i-1];
         else
            bufPrice6[i]=0;
      }else{
         bufPrice6[i]=CalcPrice(MA_Price, tmpSymbol6[h].open, tmpSymbol6[h].close, tmpSymbol6[h].high, tmpSymbol6[h].low);
      }
   }//Next i
//--- Расчёт нулевой свечи
   j = ArraySize(tmpSymbol1)-1;
   k = ArraySize(tmpSymbol2)-1;
   z = ArraySize(tmpSymbol3)-1;
   x = ArraySize(tmpSymbol4)-1;
   f = ArraySize(tmpSymbol5)-1;
   h = ArraySize(tmpSymbol6)-1;
   bufPrice1[rates_total-1]=CalcPrice(MA_Price, tmpSymbol1[j].open, tmpSymbol1[j].close, tmpSymbol1[j].high, tmpSymbol1[j].low);
   bufPrice2[rates_total-1]=CalcPrice(MA_Price, tmpSymbol2[k].open, tmpSymbol2[k].close, tmpSymbol2[k].high, tmpSymbol2[k].low);
   bufPrice3[rates_total-1]=CalcPrice(MA_Price, tmpSymbol3[z].open, tmpSymbol3[z].close, tmpSymbol3[z].high, tmpSymbol3[z].low);
   bufPrice4[rates_total-1]=CalcPrice(MA_Price, tmpSymbol4[x].open, tmpSymbol4[x].close, tmpSymbol4[x].high, tmpSymbol4[x].low);
   bufPrice5[rates_total-1]=CalcPrice(MA_Price, tmpSymbol5[f].open, tmpSymbol5[f].close, tmpSymbol5[f].high, tmpSymbol5[f].low);
   bufPrice6[rates_total-1]=CalcPrice(MA_Price, tmpSymbol6[h].open, tmpSymbol6[h].close, tmpSymbol6[h].high, tmpSymbol6[h].low);
//--- цены синхронизированнны. Переходим к основному расчёту индикатора
  //------------------------------------------------------------------ 

Терминал с аналогичной ошибкой направляет меня в этот фрагмент
      if(curTime[i]<tmpSymbol3[z].time) {
         if(i>0) //Дыра в истории инструмента 3
            bufPrice3[i]=bufPrice3[i-1];
         else
            bufPrice3[i]=0;
      }else{
         bufPrice3[i]=CalcPrice(MA_Price, tmpSymbol3[z].open, tmpSymbol3[z].close, tmpSymbol3[z].high, tmpSymbol3[z].low);
      }
а точнее в эти места, где ошибка. Причем если убрать инструмент 3-6, то все нормально работает
bufPrice3^[i]
 
ivan.berezhnuy:

Терминал с аналогичной ошибкой направляет меня в этот фрагмент а точнее в эти места, где ошибка. Причем если убрать инструмент 3-6, то все нормально работает

Если i=0, то i-1=-1. Это и есть ошибка.

 

Там же условие, если i>0
Причина обращения: