Прожорливость памяти ОЗУ MT5, проблемы с чтением/записью больших файлов - страница 6

 
Vladimir:

Рекомендую сделать сначала минимальное изменение, с тем, чтобы перевыделение памяти делалось реже. Две строки

         m_total_rows++;
         ArrayResize(m_cells,m_total_rows*m_total_columns,10000);

в bool CSVReader::AddData(string data_str,bool header) замените на

         m_total_rows++;
         if (m_total_rows*m_total_columns>ArraySize(m_cells)) ArrayResize(m_cells,2*m_total_rows*m_total_columns);

Число перевыделений памяти с копированием должно стать O(log(n,2)) вместо O(n). 20 вместо 600 тысяч. Может быть, этого Вам уже и хватит.

Спасибо! Сообщаю, что вышло:

1. По памяти изменений нет - на 10 гигабайт текущий код съел ОЗУ там и там.

2. По скорости:

2.1 Старый вариант 574 секунды

2018.07.22 02:08:18.694 Scripts script Pred_Ocenka (Si Splice,M1) loaded successfully
2018.07.22 02:17:52.059 Scripts script Pred_Ocenka (Si Splice,M1) removed

2.2 Новый вариант 138 секунд

2018.07.22 02:22:16.728 Scripts script Pred_Ocenka (Si Splice,M1) loaded successfully
2018.07.22 02:24:34.569 Scripts script Pred_Ocenka (Si Splice,M1) removed

Получается прирост в 4 раза, что весьма хорошо! Однако, память впритык, а это далеко не все, что надо загружать....

 
Maxim Dmitrievsky:

очень удобно :)

Сконвертировал я значит CSV в бинарник, за вычетом даты.

Что получается, при работе скрипт памяти отъел 1 гигабайт, что по сравнению с 10 очень хорошо. Однако, всё равно много :)

По скорости - всего 16 секунд! Весьма не дурно!

2018.07.22 02:35:12.338 Scripts script Pred_Ocenka_02 (Si Splice,M1) loaded successfully
2018.07.22 02:35:28.334 Scripts script Pred_Ocenka_02 (Si Splice,M1) removed
 
Vladimir:

Рекомендую сделать сначала минимальное изменение, с тем, чтобы перевыделение памяти делалось реже. Две строки

         m_total_rows++;
         ArrayResize(m_cells,m_total_rows*m_total_columns,10000);

в bool CSVReader::AddData(string data_str,bool header) замените на

         m_total_rows++;
         if (m_total_rows*m_total_columns>ArraySize(m_cells)) ArrayResize(m_cells,2*m_total_rows*m_total_columns);

Число перевыделений памяти с копированием должно стать O(log(n,2)) вместо O(n). 20 вместо 600 тысяч. Может быть, этого Вам уже и хватит.

Вообще-то третий параметр для ArrayResize() непросто так указан... фиговое изменение...

Документацию прочтите

 
Roffild:

Вообще-то третий параметр для ArrayResize() непросто так указан... фиговое изменение...

Документацию прочтите

Что Вам удалось выудить из документации по поводу третьего параметра, полезное для этого случая, когда решается задача подъема в память .csv, создаваемых в разных программах и имеющих произвольный размер?

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

 
Aleksey Vyazmikin:

Спасибо! Сообщаю, что вышло:

1. По памяти изменений нет - на 10 гигабайт текущий код съел ОЗУ там и там.

2. По скорости:

2.1 Старый вариант 574 секунды

2.2 Новый вариант 138 секунд

Получается прирост в 4 раза, что весьма хорошо! Однако, память впритык, а это далеко не все, что надо загружать....

После считывания, в bool CSVReader::Load(int start_line), после строки 

FileClose(filehandle);

вставьте освобождение памяти

ArrayResize(m_cells,m_total_rows*m_total_columns);

Освободит ненужные 0-50% памяти, занятой m_cells. Только самим m_cells, без содержимого ячеек.

 

Сейчас делаю небольшую библиотеку для быстрой работы с CSV.

На скрине тест работы, который проходит за 7 секунд!!! Процессор Xeon, 3.0 частота.

Сначала скрипт составляет формат данных для каждого столбца. Столбцов 6. Потом добавляется 1000000 строк в таблицу, далее они заполняются числами от 0 до 999999. Согласно формату данных числа могут восприниматься по разному. Потом сохраняется всё в файл.

Размер файла 65.4 Мб. Вся структура в памяти занимала 232 Мб.

 
Aleksey Vyazmikin:

Сконвертировал я значит CSV в бинарник, за вычетом даты.

Что получается, при работе скрипт памяти отъел 1 гигабайт, что по сравнению с 10 очень хорошо. Однако, всё равно много :)

По скорости - всего 16 секунд! Весьма не дурно!

ну сам скрипт еще корявый значит

 
Vladimir:

После считывания, в bool CSVReader::Load(int start_line), после строки 

FileClose(filehandle);

вставьте освобождение памяти

ArrayResize(m_cells,m_total_rows*m_total_columns);

Освободит ненужные 0-50% памяти, занятой m_cells. Только самим m_cells, без содержимого ячеек.

Спасибо, однако после закрытия файла/окончания работы скрипта память быстро и так освобождается. Вот как бы снизить потребление во время работы....

 
Aliaksandr Hryshyn:

Сейчас делаю небольшую библиотеку для быстрой работы с CSV.

На скрине тест работы, который проходит за 7 секунд!!! Процессор Xeon, 3.0 частота.

Сначала скрипт составляет формат данных для каждого столбца. Столбцов 6. Потом добавляется 1000000 строк в таблицу, далее они заполняются числами от 0 до 999999. Согласно формату данных числа могут восприниматься по разному. Потом сохраняется всё в файл.

Размер файла 65.4 Мб. Вся структура в памяти занимала 232 Мб.

Весьма интересно. Вы планируете публично опубликовать свои достижения в программировании?

 
Maxim Dmitrievsky:

ну сам скрипт еще корявый значит

Можете сказать, что в нём исправить?

#property version   "1.00"
#property indicator_chart_window
#property strict
//---
#property script_show_inputs
//#include <CSVReader.mqh>                              //Класс по чтению информации из файла
#include <CsvWriter_2.mqh>                            //Класс по записи информации в файл

input string  FileLoadSetup="PredFind\\Test\\Pred_Ocenka_Read.csv";
input int Prediktor=1; //Целевая
input double Support=0.01;//Поддержка
input double Relevantnost=70.0;//Достоверность

//---Переменные
int ArrTest[][57];

CsvWriter Printer;
int Statistic;

int StrokTotal=0;
int arrSize=0;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int arrTest2[][57];
   int r=FileOpen("PredFind\\Test\\test.bin",FILE_BIN|FILE_READ);
   if(r!=INVALID_HANDLE) 
     { 
      FileReadArray(r,arrTest2,0,WHOLE_ARRAY);
      Print(arrTest2[1][1]);
      arrSize=ArraySize(arrTest2)/57;
      StrokTotal=arrSize;
      Print(arrSize);

     ArrayFree(ArrTest); 
     ArrayResize(ArrTest,arrSize);

      for(int i=1;i<StrokTotal; i++)
        {
         for(int s=1;s<56+1; s++)
           {   
            //Print("s=",s);
            ArrTest[i,s]=arrTest2[i,s];
           }
        }
         Print(ArrTest[2,1]);
      for(int i=1;i<StrokTotal; i++)
        {
         for(int s=3;s<56+1; s++)
           {               
            if (ArrTest[i,s]>=0)ArrTest[i,s]=ArrTest[i,s]*ArrTest[i,1];
            else ArrTest[i,s]=ArrTest[i,s]*ArrTest[i,2];
           }
        }
   }
     else Print("File open failed, error ",GetLastError()); 
/*    
   int h=FileOpen("PredFind\\Test\\test.bin",FILE_BIN|FILE_WRITE);
   FileWriteArray(h,ArrTest,0,WHOLE_ARRAY);
   FileClose(h);
*/
   
    
   string TimeF=TimeToString(TimeLocal(),TIME_DATE|TIME_MINUTES);
   StringSetCharacter(TimeF,13,'_');
   Statistic=Printer.FileCreate(Symbol()+"_"+TimeF+"_""Pred_Ocenka_Write","PredFind\\Test",false,false,EvryTick); //Создание файла для записи     
   Printer.Write(
                 "arr_Data",
                 "arr_Buy_Sell",
                 "arr_Buy_Sell"
                 );

   for(int i=1;i<arrSize; i++)
     {
      Printer.Write(
                    IntegerToString(0),
                    IntegerToString(ArrTest[i,1]),
                    IntegerToString(ArrTest[i,2]),
                    IntegerToString(ArrTest[i,3]),
                    IntegerToString(ArrTest[i,4]),
                    IntegerToString(ArrTest[i,5]),
                    IntegerToString(ArrTest[i,6]),
                    IntegerToString(ArrTest[i,7]),
                    IntegerToString(ArrTest[i,8]),
                    IntegerToString(ArrTest[i,9]),
                    IntegerToString(ArrTest[i,10]),
                    IntegerToString(ArrTest[i,11]),
                    IntegerToString(ArrTest[i,12]),
                    IntegerToString(ArrTest[i,13]),
                    IntegerToString(ArrTest[i,14]),
                    IntegerToString(ArrTest[i,15]),
                    IntegerToString(ArrTest[i,16]),
                    IntegerToString(ArrTest[i,17]),
                    IntegerToString(ArrTest[i,18]),
                    IntegerToString(ArrTest[i,19]),
                    IntegerToString(ArrTest[i,20]),
                    IntegerToString(ArrTest[i,21]),
                    IntegerToString(ArrTest[i,22]),
                    IntegerToString(ArrTest[i,23]),
                    IntegerToString(ArrTest[i,24]),
                    IntegerToString(ArrTest[i,25]),
                    IntegerToString(ArrTest[i,26]),
                    IntegerToString(ArrTest[i,27]),
                    IntegerToString(ArrTest[i,28]),
                    IntegerToString(ArrTest[i,29]),
                    IntegerToString(ArrTest[i,30]),                                                                                
                    IntegerToString(ArrTest[i,31]),
                    IntegerToString(ArrTest[i,32]),
                    IntegerToString(ArrTest[i,33]),
                    IntegerToString(ArrTest[i,34]),
                    IntegerToString(ArrTest[i,35]),
                    IntegerToString(ArrTest[i,36]),
                    IntegerToString(ArrTest[i,37]),
                    IntegerToString(ArrTest[i,38]),
                    IntegerToString(ArrTest[i,39]),
                    IntegerToString(ArrTest[i,40]),
                    IntegerToString(ArrTest[i,41]),
                    IntegerToString(ArrTest[i,42]),
                    IntegerToString(ArrTest[i,43]),
                    IntegerToString(ArrTest[i,44]),
                    IntegerToString(ArrTest[i,45]),
                    IntegerToString(ArrTest[i,46]),
                    IntegerToString(ArrTest[i,47])
                    );
     }
  }