MT5 RAM内存贪婪,读/写大文件的问题 - 页 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++;
如果(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,而不是60万。也许现在对你来说这就够了。

谢谢你!我想让你知道我得到了什么。

1.内存没有变化--通过10千兆字节,目前的代码在那里和那里吃了RAM。

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,而不是60万。也许这对你来说就足够了。

事实上,ArrayResize() 的第三个参数被指定是有原因的...这是个糟糕的变化。

阅读文件

 
Roffild:

事实上,ArrayResize()的第三个参数被指定是有原因的...羽翼丰满的变化...

阅读文件

关于第三个参数,你从文档中了解到了什么?在解决将不同程序创建的、具有任意大小的.csv文件提升到内存中的问题时,第三个参数对这种情况很有用。

欢迎提出更好的、非二进制的改变,它比二进制搜索更能提高内存重新分配的速度(减少ArrayResize的调用次数)...

 
Aleksey Vyazmikin:

谢谢你!我会让你知道结果的。

1.内存没有变化--通过10千兆字节,目前的代码在那里和那里吃了RAM。

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)。

释放被m_cells占用的不必要的0-50%的内存。只有m_cells本身,没有单元格内容。

 

现在我正在做一个小的库,以快速处理CSV。

截图上是一个测试运行,在7秒内通过!!!。Xeon处理器,3.0频率。

首先,脚本为每一列制定了数据格式。有6个栏目。然后将1000000行添加到表中,然后用0到999999的数字来填充它们。根据数据格式,这些数字可以被认为是不同的。然后,所有的东西都被保存到一个文件中。

文件大小为65.4MB。整个结构占用了232MB的内存。

 
Aleksey Vyazmikin:

所以我把CSV转换为二进制,减去日期。

事实证明,当运行脚本时,占用了1千兆字节的内存,与10兆字节相比,这是非常好的。然而,仍然有很多 :)

就速度而言--只有16秒!这是最重要的。相当不错!

好吧,脚本本身仍然是残缺的。

 
Vladimir:

读取后,在bool CSVReader::Load(int start_line)中,在行后

FileClose(filehandle)。

插入内存释放

ArrayResize(m_cells,m_total_rows*m_total_columns)。

释放被m_cells占用的不必要的0-50%的内存。只有m_cells本身,没有单元格内容。

谢谢,但在关闭文件/完成脚本后,无论如何,内存会很快被释放。以下是如何在运行时减少消耗的方法....

 
Aliaksandr Hryshyn:

现在我正在做一个小的库,以快速处理CSV。

截图上是一个测试运行,在7秒内通过!!!。Xeon处理器,3.0频率。

首先,脚本为每一列制定了数据格式。有6个栏目。然后将1000000行添加到表中,然后用0到999999的数字来填充它们。根据数据格式,这些数字可以被认为是不同的。然后所有的东西都被保存到一个文件中。

文件大小为65.4MB。整个结构占用了232MB的内存。

相当有趣。你是否打算公开发表你的编程成就?

 
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])
                    );
     }
  }