voracidade da memória MT5 RAM, problemas com a leitura/escrita de arquivos grandes

Aleksey Vyazmikin  

Tenho uma pergunta, meu arquivo CSV tem 78 megabytes de tamanho, quero calculá-lo, pois o Excel é muito lento por causa de seu tamanho, eu estava pensando em usar o MT5.

Eu fiz um roteiro que só lê dados em matrizes para cada linha (57 matrizes para leitura de arquivo e 57 para escrita em novo arquivo), o tamanho da matriz é igual ao número de linhas no arquivo CSV. Então, o script comeu 8 gigabytes de memória, enquanto o Excel tem menos de 1,5 gigabytes, e a operação de leitura/gravação levou MT5 até 9 minutos!

Roffild  

Ao menos coloque o código em MQL... Você tem que contar linha por linha.

SQL, Apache Spark ou outras variantes são utilizadas para tais tarefas.

Aleksey Vyazmikin  
Roffild:

Ao menos coloque o código em MQL ... Linha por linha deve ser calculada.

Para tais tarefas e utiliza SQL, Apache Spark ou outras opções.

Ainda não tenho cálculos lá, é só que escrever para a matriz leva tanto tempo por razões desconhecidas (na verdade, é a leitura do arquivo que consome o tempo, ainda não está claro sobre a memória).

Eu não excluo um problema com o código. Estou usando a classe de leitura, tweaked (tipo de regras) do MT4.

O código principal é quase 700 linhas - nada interessante lá - declaramos array, redefinimos array para zero, mudamos o tamanho do array, escrevemos dados para array de arquivo, substituímos dados de array para array, escrevemos dados de array para arquivo.

Aqui está a classe pela qual o dinheiro foi pago:

//+------------------------------------------------------------------+
//|                                                    CSVReader.mqh |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property strict
//+------------------------------------------------------------------+
//| CSVReader                                                        |
//+------------------------------------------------------------------+
class CSVReader
  {
private:
   int               m_flags;
   string            m_filename;
   char              m_delimiter;
   bool              m_data_loaded;
   //---
   string            m_column_names[];
   string            m_cells[];
   //---
   int               m_total_rows;
   int               m_total_columns;
   //---
   bool              AddData(string data_str,bool header);
   bool              CheckIndexes(int row,int column);
   string            ReplaceCommaByDot(string str);
public:
                     CSVReader(string path);
   //---
   void              SetDelimiter(char delimiter);
   void              SetCommon(bool common);
   //---
   bool              Load(int start_line);
   //---
   string            GetStringValue(int row,int column);
   int               GetIntValue(int row,int column);
   double            GetDoubleValue(int row,int column);
   bool              GetBoolValue(int row,int column);
   //---
   int               TotalRows() {return(m_total_rows);}
   int               TotalColumns() {return(m_total_columns);}
//---
   string            FileName() {return(m_filename);}
   //---
   string            ColumnName(int index);
  };
//+------------------------------------------------------------------+
//| CSVReader class constructor                                      |
//+------------------------------------------------------------------+
void CSVReader::CSVReader(string filename)
  {
   m_filename=filename;
   m_flags=FILE_SHARE_READ|FILE_TXT|FILE_ANSI;
   m_delimiter=';';
   m_data_loaded=false;
   ArrayResize(m_column_names,0);
   ArrayResize(m_cells,0);
   m_total_rows=0;
   m_total_columns=0;
  }
//+------------------------------------------------------------------+
//| SetDelimiter                                                     |
//+------------------------------------------------------------------+
void CSVReader::SetDelimiter(char delimiter)
  {
   m_delimiter=delimiter;
  }
//+------------------------------------------------------------------+
//| SetCommon                                                        |
//+------------------------------------------------------------------+
void CSVReader::SetCommon(bool common)
  {
   if(common) m_flags|=FILE_COMMON;
   else m_flags&=~FILE_COMMON;
  }
//+------------------------------------------------------------------+
//| ColumnName                                                       |
//+------------------------------------------------------------------+
string CSVReader::ColumnName(int index)
  {
   if(m_total_columns==0) return("");
   if((index>=0) && (index<m_total_columns)) return(m_column_names[index]);
   return("error");
  }
//+------------------------------------------------------------------+
//| AddData                                                          |
//+------------------------------------------------------------------+
bool CSVReader::AddData(string data_str,bool header)
  {
   string str=data_str;

  int DlinaStroki=StringLen(str);
  int ObrezLeft=StringTrimLeft(str);
  int ObrezRifgr=StringTrimRight(str);
   if(ObrezLeft>0)
   {
   str=StringSubstr( 
        str,              // строка 
        ObrezLeft,        // с какой позиции начать 
        DlinaStroki-ObrezLeft         // длина извлекаемой строки 
   );
   ObrezRifgr=StringTrimRight(str);
   }
   if(ObrezRifgr>0)
   {
   str=StringSubstr( 
        str,              // строка 
        0,        // с какой позиции начать 
        DlinaStroki-ObrezRifgr         // длина извлекаемой строки 
   );
   }
   
   
//   str=StringTrimLeft(str);
//   str=StringTrimRight(str);
//---
   if(StringLen(str)==0) return(false);
   string lines[];
   StringSplit(str,m_delimiter,lines);
//--- check ending with delimiter
   if(StringLen(str)>0)
     {
      string str0=StringSubstr(str,StringLen(str)-1,1);
      //--- ending with delimiter case, decrease lines[]
      if(str0==CharToString(m_delimiter))
        {
         ArrayResize(lines,ArraySize(lines)-1);
        }
     }
//--- parse header
   if(header==true)
     {
      m_total_columns=ArraySize(lines);
      if(m_total_columns==0) return(false);
      ArrayResize(m_column_names,m_total_columns);
      //---
      for(int i=0; i<m_total_columns; i++)
        {
         m_column_names[i]=lines[i];
        }
     }
   else
//--- parse data
     {
      int columns_count=ArraySize(lines);
      //--- add data
      if(columns_count==m_total_columns)
        {
         m_total_rows++;
         ArrayResize(m_cells,m_total_rows*m_total_columns,10000);
         //---
         for(int i=0; i<columns_count; i++)
           {
            int index=m_total_columns*(m_total_rows-1)+i;
            if((index>=0) && (index<ArraySize(m_cells)))
              {
               m_cells[index]=ReplaceCommaByDot(lines[i]);
              }
            else return(false);
           }
        }
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Load                                                             |
//+------------------------------------------------------------------+
bool CSVReader::Load(int start_line)
  {
   int filehandle=FileOpen(m_filename,FILE_CSV|FILE_READ|FILE_ANSI|FILE_SHARE_READ,'\n');
   if(filehandle==INVALID_HANDLE)
     {
      Alert("Error in open of file ",m_filename,", error",GetLastError());
      return(false);
     }
//---
   int line_index=0;
   while(!FileIsEnding(filehandle))
     {
      string str=FileReadString(filehandle);
      //--- skip 0th row
      if(line_index>=start_line)
         if(str!="")
           {
            if(line_index==1) AddData(str,true);
            else AddData(str,false);
           }
      line_index++;
     }
//---
   FileClose(filehandle);
   return(true);
  }
//+------------------------------------------------------------------+
//| ReplaceCommaByDot                                                |
//+------------------------------------------------------------------+
string CSVReader::ReplaceCommaByDot(string str)
  {
   string str0="";
   for(int i=0; i<StringLen(str); i++)
     {
      ushort chr=StringGetCharacter(str,i);
      if(chr==',') chr='.';
      str0+=CharToString((uchar)chr);
     }
   return(str0);
  }
//+------------------------------------------------------------------+
//| CheckIndexes                                                     |
//+------------------------------------------------------------------+
bool CSVReader::CheckIndexes(int row,int column)
  {
   if((m_total_columns==0) || (m_total_rows==0)) return(false);
   if((row<0) || (row>=m_total_rows)) return(false);
   if((column<0) || (column>=m_total_columns)) return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| GetStringValue                                                   |
//+------------------------------------------------------------------+
string CSVReader::GetStringValue(int row,int column)
  {
   if(CheckIndexes(row,column)==false) return("");
//---
   int index=m_total_columns*row+column;
   if((index>=0) && (index<ArraySize(m_cells))) return(m_cells[index]);
   return("error");
  }
//+------------------------------------------------------------------+
//| GetIntValue                                                      |
//+------------------------------------------------------------------+
int CSVReader::GetIntValue(int row,int column)
  {
   if(CheckIndexes(row,column)==false) return(0);
//---
   int index=m_total_columns*row+column;
   if((index>=0) && (index<ArraySize(m_cells)))
     {
      return((int)StringToInteger(m_cells[index]));
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| GetDoubleValue                                                   |
//+------------------------------------------------------------------+
double CSVReader::GetDoubleValue(int row,int column)
  {
   if(CheckIndexes(row,column)==false) return(0.0);
//---
   int index=m_total_columns*row+column;
   if((index>=0) && (index<ArraySize(m_cells)))
     {
      return(StringToDouble(m_cells[index]));
     }
   return(0.0);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| GetBoolValue                                                   |
//+------------------------------------------------------------------+
bool CSVReader::GetBoolValue(int row,int column)
  {
   if(CheckIndexes(row,column)==false) return(0.0);
//---
   int index=m_total_columns*row+column;
   if((index>=0) && (index<ArraySize(m_cells)))
     {
      if (StringToInteger(m_cells[index])==1) return (true);
      else return (false);
     }
   return(0.0);
  }
//+------------------------------------------------------------------+

O roteiro (a escrita é omitida, porque o problema é com a leitura) é uma versão despojada.

#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 arrRead_01[];
int arrRead_02[];
int arrRead_03[];

//--Информационные
string arrRead_DateTime[];

int arrWrite_01[];
int arrWrite_02[];
int arrWrite_03[];

//--Информационные
string arrWrite_DateTime[];

CsvWriter Printer;
int Statistic;

int StrokTotal=0;
int arrSize=0;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {

   CSVReader FileLoads(FileLoadSetup);
   FileLoads.SetDelimiter(';');
   FileLoads.SetCommon(true);
   int StrokaSetup=0;
   if(FileLoads.Load(1))
     {
      StrokTotal=FileLoads.TotalRows();
      arrSize=StrokTotal;
      PrintFormat("File%s loaded. Total rows=%d,Total columns=%d",FileLoads.FileName(),FileLoads.TotalRows(),FileLoads.TotalColumns());


      ArrayFree(arrRead_01);
      ArrayFree(arrRead_02);
      ArrayFree(arrRead_03);
      ArrayFree(arrRead_DateTime);
    
      ArrayFree(arrWrite_01);
      ArrayFree(arrWrite_02);
      ArrayFree(arrWrite_03);
      ArrayFree(arrWrite_DateTime);
      
      
      
      //--Зададим размер массивам
     
      ArrayResize(arrRead_01,arrSize);
      ArrayResize(arrRead_02,arrSize);
      ArrayResize(arrRead_03,arrSize);
      ArrayResize(arrRead_DateTime,arrSize);
 
      ArrayResize(arrWrite_01,arrSize);
      ArrayResize(arrWrite_02,arrSize);
      ArrayResize(arrWrite_03,arrSize);
      ArrayResize(arrWrite_DateTime,arrSize);

      for(int i=1;i<StrokTotal; i++)
        {
         //Print(FileLoads.GetIntValue(i,20));
        }

      for(int i=1;i<StrokTotal; i++)
        {
         arrRead_DateTime[i]=FileLoads.GetStringValue(i,0);        
         arrRead_01[i]=FileLoads.GetIntValue(i,1);
         arrRead_02[i]=FileLoads.GetIntValue(i,2);
         arrRead_03[i]=FileLoads.GetIntValue(i,3);
        }

     }

   for(int i=1;i<arrSize; i++)
     {
         arrWrite_DateTime[i]=arrRead_DateTime[i];
         arrWrite_01[i]=arrRead_01[i];
         arrWrite_02[i]=arrRead_02[i];
         arrWrite_03[i]=arrRead_03[i];
     }

  }
//+------------------------------------------------------------------+
Arquivos anexados:
Aleksey Vyazmikin  

Há mais um problema - não consigo descobrir como escrever mais de 48 colunas. Eu também uso a classe. Alguém pode ajudar a corrigir a classe a fim de expandir o número de colunas para o registro?

Aqui está o código que está faltando no post anterior paraescrever em um arquivo .

   string TimeF= TimeToString ( TimeLocal (), TIME_DATE | TIME_MINUTES );
   StringSetCharacter (TimeF, 13 , '_' );
   Statistic=Printer.FileCreate( Symbol ()+ "_" + "Pred_Ocenka_Write" , "PredFind\\Test" , false , false ,EvryTick); //Создание файла для записи     
   Printer.Write(
                 "arr_Buy_Sell" ,
                 "arr_Vektor_Week" ,
                 "arr_Vektor_Day" ,
                 "arr_Vektor_Don" ,
                 "arr_DonProc" ,
                 "arr_iDelta_H_1_H1" ,
                 "arr_iDelta_H_1_H3" ,
                 "arr_iDelta_H_1_H4" ,
                 "arr_iDelta_H_1_H6" ,
                 "arr_iDelta_H_1_H12" ,
                 "arr_iDelta_H_1_D1" ,
                 "arr_iDelta_H_1_W1" ,
                 "arr_iDelta_H_1_MN1" ,
                 "arr_RSI_Open_M1" ,
                 "arr_RSI_Open_H1" ,
                 "arr_BB_Center" ,
                 "arr_BB_Up" ,
                 "arr_BB_Down" ,
                 "arr_TimeH" ,
                 "arr_Den_Nedeli" ,
                 "arr_iDelta_Max_H1" ,
                 "arr_iDelta_Min_H1" ,
                 "arr_iDelta_Max_D1" ,
                 "arr_iDelta_Min_D1" ,
                 "arr_Buy Расчетная" ,
                 "arr_Buy Номер правила" ,
                 "arr_Buy Поддержка" ,
                 "arr_Buy Достоверность"
                 );

   for ( int i= 1 ;i<arrSize; i++)
     {
      Printer.Write(
                     arrRead_DateTime[i],
                     IntegerToString (arrWrite_01[i]),
                     IntegerToString (arrWrite_02[i]),
                     IntegerToString (arrWrite_03[i]),
                     IntegerToString (arrWrite_04[i]),
                     IntegerToString (arrWrite_05[i]),
                     IntegerToString (arrWrite_06[i]),
                     IntegerToString (arrWrite_07[i]),
                     IntegerToString (arrWrite_08[i]),
                     IntegerToString (arrWrite_09[i]),
                     IntegerToString (arrWrite_10[i]),
                     IntegerToString (arrWrite_11[i]),
                     IntegerToString (arrWrite_12[i]),
                     IntegerToString (arrWrite_13[i]),
                     IntegerToString (arrWrite_14[i]),
                     IntegerToString (arrWrite_15[i]),
                     IntegerToString (arrWrite_16[i]),
                     IntegerToString (arrWrite_17[i]),
                     IntegerToString (arrWrite_18[i]),
                     IntegerToString (arrWrite_19[i]),
                     IntegerToString (arrWrite_20[i]),
                     IntegerToString (arrWrite_21[i]),
                     IntegerToString (arrWrite_22[i]),
                     IntegerToString (arrWrite_23[i]),
                     IntegerToString (arrWrite_24[i]),
                     IntegerToString (arrWrite_25[i]),
                     IntegerToString (arrWrite_26[i]),
                     IntegerToString (arrWrite_27[i]),
                     IntegerToString (arrWrite_28[i]),
                     IntegerToString (arrWrite_29[i]),
                     IntegerToString (arrWrite_30[i]),                                                                                
                     IntegerToString (arrWrite_40[i]),
                     IntegerToString (arrWrite_41[i]),
                     IntegerToString (arrWrite_42[i]),
                     IntegerToString (arrWrite_43[i]),
                     IntegerToString (arrWrite_44[i]),
                     IntegerToString (arrWrite_45[i]),
                     IntegerToString (arrWrite_46[i]),
                     IntegerToString (arrWrite_47[i]),
                     IntegerToString (arrWrite_48[i]),
                     IntegerToString (arrWrite_49[i]),
                     IntegerToString (arrWrite_50[i]),
                     IntegerToString (arrWrite_51[i]),
                     IntegerToString (arrWrite_52[i]),
                     IntegerToString (arrWrite_53[i]),
                     IntegerToString (arrWrite_54[i]),
                     IntegerToString (arrWrite_55[i]),
                     IntegerToString (arrWrite_56[i])
                    );
     }

Mas a classe para gravar dados em um arquivo também é paga

 //+------------------------------------------------------------------+
//|                                                    CsvWriter.mqh |
//|                                                Виктор Крупинский |
//|                                               Krupinskiy@Mail.Ru |
//+------------------------------------------------------------------+
#property copyright "Виктор Крупинский"
#property link        "Krupinskiy@Mail.Ru"
#property version    "2.00"
#property strict

enum periodicity { EvryTick=- 1 ,NewBar= PERIOD_CURRENT ,EvryHour= PERIOD_H1 ,
                     EvryDay= PERIOD_D1 ,EvryWeek= PERIOD_W1 ,EvryMonth= PERIOD_MN1 };
class CsvWriter {
private :
   int handle;
   periodicity writeperiod; 
   datetime opentime; 
   bool flag;
   string DotToComma( string value);
public :
   CsvWriter() { flag= false ; };
   ~CsvWriter() { if (flag) FileClose (handle); };
   int FileCreate( string fileame, string Dir= "" , bool Common= false , bool FileNew= true ,periodicity period=EvryTick);
   void FileSelectByHandle( int h,periodicity period=EvryTick) { handle=h; SetPeriodicity(period);};
   void SetPeriodicity(periodicity period);   
   int Write( string T1, string T2= "" , string T3= "" , string T4= "" , string T5= "" , string T6= "" , string T7= "" ,
             string T8= "" , string T9= "" , string T10= "" , string T11= "" , string T12= "" , string T13= "" , string T14= "" ,
             string T15= "" , string T16= "" , string T17= "" , string T18= "" , string T19= "" , string T20= "" , string T21= "" ,
             string T22= "" , string T23= "" , string T24= "" , string T25= "" , string T26= "" , string T27= "" , string T28= "" ,
             string T29= "" , string T30= "" , string T31= "" , string T32= "" , string T33= "" , string T34= "" , string T35= "" ,
             string T36= "" , string T37= "" , string T38= "" , string T39= "" , string T40= "" , string T41= "" , string T42= "" ,
             string T43= "" , string T44= "" , string T45= "" , string T46= "" , string T47= "" , string T48= "" , string T49= "" ,
             string T50= "" , string T51= "" , string T52= "" , string T53= "" , string T54= "" , string T55= "" , string T56= "" ,
             string T57= "" , string T58= "" , string T59= "" , string T60= "" , string T61= "" , string T62= "" , string T63= "" ) {  
       int ReturnValue= 0 ;   
       if (writeperiod==- 1 || opentime!=iTime_Old( _Symbol ,writeperiod, 0 )) {
         if ( FileWrite (handle,DotToComma(T1),DotToComma(T2),DotToComma(T3),DotToComma(T4),DotToComma(T5),DotToComma(T6),
                  DotToComma(T7),DotToComma(T8),DotToComma(T9),DotToComma(T10),DotToComma(T11),DotToComma(T12),
                  DotToComma(T13),DotToComma(T14),DotToComma(T15),DotToComma(T16),DotToComma(T17),DotToComma(T18),
                  DotToComma(T19),DotToComma(T20),DotToComma(T21),DotToComma(T22),DotToComma(T23),DotToComma(T24),
                  DotToComma(T25),DotToComma(T26),DotToComma(T27),DotToComma(T28),DotToComma(T29),DotToComma(T30),
                  DotToComma(T31),DotToComma(T32),DotToComma(T33),DotToComma(T34),DotToComma(T35),DotToComma(T36),
                  DotToComma(T37),DotToComma(T38),DotToComma(T39),DotToComma(T40),DotToComma(T41),DotToComma(T42),
                  DotToComma(T43),DotToComma(T44),DotToComma(T45),DotToComma(T46),DotToComma(T47),DotToComma(T48),
                  DotToComma(T49),DotToComma(T50),DotToComma(T51),DotToComma(T52),DotToComma(T53),DotToComma(T54),
                  DotToComma(T55),DotToComma(T56),DotToComma(T57),DotToComma(T58),DotToComma(T59),DotToComma(T60),
                  DotToComma(T61),DotToComma(T62),DotToComma(T63))) {
            ReturnValue= 1 ;
             FileFlush (handle);
         }
      }
      opentime = writeperiod==EvryTick ? 0 : iTime_Old( _Symbol ,writeperiod, 0 );
       return (ReturnValue);
   }; //--------------------------------- End Write -------------------------------------
}; //--------------------- End CsvWriter ------------------------------------------------
int CsvWriter::FileCreate( string filename, string Dir= "" , bool Common= false , bool FileNew= true ,
                           periodicity period=EvryTick) {
                           //Print ("Попытка создать файл");
   if (FileNew) {
   //Print ("Новый файл?");
       string NextName;   
       int Pos;
       string Filter = Dir== "" ? "*" : Dir+ "\\*" ;
       long SearchHandle=Common ? FileFindFirst (Filter,NextName, FILE_COMMON ) : FileFindFirst (Filter,NextName);
       int Count = StringFind (NextName,filename)>= 0 && (Pos= StringFind (NextName, "_" ))> 0 ? 
                  ( int ) StringSubstr (NextName, 0 ,Pos) : 0 ;
      NextName= "" ;
       while ( FileFindNext (SearchHandle,NextName))
         if ( StringFind (NextName,filename)>= 0 && (Pos= StringFind (NextName, "_" ))> 0 )
            Count= MathMax (Count,( int ) StringSubstr (NextName, 0 ,Pos));        
       FileFindClose (SearchHandle);
      Count++;
      filename= IntegerToString (Count, 6 , '0' )+ "_" +filename;
   }
   filename = (Dir== "" ? filename : Dir+ "\\" +filename)+ ".csv" ;
   handle= Common ? FileOpen (filename, FILE_CSV | FILE_COMMON | FILE_READ | FILE_WRITE | FILE_SHARE_READ ) :
                         FileOpen (filename, FILE_CSV | FILE_READ | FILE_WRITE | FILE_SHARE_READ );
                       // Print ("handle=",handle);
   flag=handle> 0 ;
   if (handle> 0 ) {                          
       FileSeek (handle, 0 , SEEK_END );
       ulong pos= FileTell (handle);
      SetPeriodicity(period);
   }
   return (handle);   
} //---------------------- End FileCreate ------------------------------------------------
void CsvWriter::SetPeriodicity(periodicity period) {
   writeperiod = period; 
   opentime = period==EvryTick ? 0 : iTime_Old( _Symbol ,period, 0 );
} //---------------------- End SetPeriodicity --------------------------------------------
string CsvWriter::DotToComma( string value) {
   int Pos= 0 ;
   if ((Pos= StringFind (( string )value, "." ))>= 0 && StringFind ( StringSubstr (( string )value,Pos+ 1 ), "." )< 0 )
       //value=StringSetChar(value,Pos,',');
       //Print (value);
         StringSetCharacter (value,Pos, ',' );
       //Print (value);
   return (value);
} //---------------------- End DotToComma ------------------------------------------------
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime iTime_Old( string symbol, int tf, int index)
  {
   if (index < 0 ) return (- 1 );
   ENUM_TIMEFRAMES timeframe=TFMigrate_Old(tf);
   datetime Arr[];
   if ( CopyTime (symbol,timeframe,index, 1 ,Arr)> 0 )
       return (Arr[ 0 ]);
   else return (- 1 );
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES TFMigrate_Old( int tf)
  {
   switch (tf)
     {
       case 0 : return ( PERIOD_CURRENT );
       case 1 : return ( PERIOD_M1 );
       case 5 : return ( PERIOD_M5 );
       case 15 : return ( PERIOD_M15 );
       case 30 : return ( PERIOD_M30 );
       case 60 : return ( PERIOD_H1 );
       case 240 : return ( PERIOD_H4 );
       case 1440 : return ( PERIOD_D1 );
       case 10080 : return ( PERIOD_W1 );
       case 43200 : return ( PERIOD_MN1 );

       case 2 : return ( PERIOD_M2 );
       case 3 : return ( PERIOD_M3 );
       case 4 : return ( PERIOD_M4 );
       case 6 : return ( PERIOD_M6 );
       case 10 : return ( PERIOD_M10 );
       case 12 : return ( PERIOD_M12 );
       case 16385 : return ( PERIOD_H1 );
       case 16386 : return ( PERIOD_H2 );
       case 16387 : return ( PERIOD_H3 );
       case 16388 : return ( PERIOD_H4 );
       case 16390 : return ( PERIOD_H6 );
       case 16392 : return ( PERIOD_H8 );
       case 16396 : return ( PERIOD_H12 );
       case 16408 : return ( PERIOD_D1 );
       case 32769 : return ( PERIOD_W1 );
       case 49153 : return ( PERIOD_MN1 );
       default : return ( PERIOD_CURRENT );
     }
  }  
Anexei todo o script.
Arquivos anexados:
Roffild  

78 Mbytes - deve haver cerca de 1.000.000 linhas.

Primeiro o arquivo inteiro é copiado para a memória. Em seguida, 4 matrizes do tipo int (8 bytes) multiplicadas pelo número de linhas. É claro que a RAM vai se esgotar rapidamente.

Para trabalhar com arquivos grandes, a leitura e a escrita devem ser feitas setor por setor, e aqui até mesmo a memória desnecessária não é liberada.
Aleksey Vyazmikin  
Roffild:

78 Mbytes - deve haver cerca de 1.000.000 linhas.

Primeiro o arquivo inteiro é copiado para a memória. Em seguida, 4 matrizes do tipo int (8 bytes) multiplicadas pelo número de linhas. É claro que a RAM vai se esgotar rapidamente.

Para trabalhar com grandes arquivos eu preciso ler e escrever setor por setor, mas aqui nem mesmo a memória desnecessária é liberada.

Há 606004 linhas no arquivo.

Não exlletem dados copiados para a memória?

Talvez tivéssemos que lidar com o arquivo de alguma outra forma, já que a maioria do tempo é gasto lendo dados do arquivo e eu não entendo porque é assim.

Preciso de um conjunto completo em memória para continuar trabalhando, caso contrário, passo muito mais tempo para ler/escrever.

Vladimir  
Aleksey Vyazmikin:

Tenho uma pergunta, meu arquivo CSV tem 78 megabytes de tamanho, quero calculá-lo, pois o Excel é muito lento por causa de seu tamanho, eu estava pensando em usar o MT5.

Eu fiz um roteiro que só lê dados em arrays para cada linha (57 arrays para leitura de arquivo e 57 para escrita em novo arquivo), o tamanho do array é igual ao número de linhas no arquivo CSV. Assim, o script comeu 8 Gbytes de memória, enquanto o Excel tinha menos de 1,5 Gbytes, e a operação de leitura/gravação levou MT5 até 9 minutos!

Você tem 600 000 cordas, cada uma contendo até 57 células que são lidas em um array unidimensional de cordas m_cells[]; ou seja, 36 milhões de elementos de cordas no array. O tipo de corda, eu me lembro, leva 12 bytes até mesmo para uma corda vazia. São 400 MB de informações de serviço (endereços, comprimentos de cordas), mesmo que todas as células estejam vazias. Veja o que acontece quando você faz um redimensionamento desta matriz ao adicionar uma nova linha:

m_total_rows++;
ArrayResize(m_células,m_total_linhas*m_total_colunas,10000);

- para cada um dos 36 milhões de células de linha, você tem que encontrar um pedaço de memória livre por tempo suficiente, agarrá-lo, copiar o valor para um novo local, e soletrar o comprimento. O fato de que 10 mil elementos (ou bytes, não me lembro) mais memória é alocada não importa: quando mais uma fileira vier, m_total_rows aumentará novamente, m_total_rows*m_total_colunas também, e novamente a memória para a matriz será realocada através de cópia. Esta é a razão pela qual o roteiro leva tanto tempo.

A memória é alocada em pedaços múltiplos de 8 bytes, mesmo para sistemas operacionais de 32 bits. Podemos assumir que m_cells não leva (400 + 78) MB, mas 1 Gb. Para cada cópia, precisamos de tanto mais espaço de memória quanto m_cells já ocupa, a duplicação da memória ocuparia 2 GB de memória. Ao invés de 78 MB, que contém as informações reais.

Em resumo, é uma forma muito ineficiente de armazenar em células de corda. É difícil ser mais específico sem conhecer a tarefa.

Konstantin Erin  
Tente jogar fora ArraySize() e ArrayResize() - você sabe o tamanho. Pegue o dobro do tamanho só para o caso de... Informe-me o resultado
Vladislav Andruschenko  
Konstantin Erin:
Tente eliminar as funções ArraySize( ) e ArrayResize() - você sabe o tamanho. Para estar no lado seguro, tome 2 vezes mais. Resultados do relatório
Aleksey Vyazmikin:

Tenho uma pergunta, meu arquivo CSV tem 78 megabytes de tamanho, quero calculá-lo, pois o Excel é muito lento por causa de seu tamanho, eu estava pensando em usar o MT5.

Eu fiz um roteiro que só lê dados em arrays para cada linha (57 arrays para leitura de arquivo e 57 para escrita em novo arquivo), o tamanho do array é igual ao número de linhas no arquivo CSV. Assim, o script comeu 8 Gbytes de memória, enquanto o Excel tinha menos de 1,5 Gbytes, e a operação de leitura/gravação levou MT5 até 9 minutos!


Eu tive este problema uma vez. Fez muitos consertos. Não consigo me lembrar de tudo isso - foi um trabalho único,

mas tente definirArrayResize(arrRead_01,arrSize); 3 parâmetro


intreserve_size=0// valor do tamanho da reserva (excesso )


Experiência.

Aleksey Vyazmikin  
Vladimir:

Você tem 600 mil cordas, cada uma contendo até 57 células, que são lidas em um array unidimensional de cordas m_cells[]; ou seja, 36 milhões de elementos de cordas no array. O tipo de corda, eu me lembro, leva 12 bytes até mesmo para uma corda vazia. São 400 MB de informações de serviço (endereços, comprimentos de cordas), mesmo que todas as células estejam vazias. Veja o que acontece quando você faz um redimensionamento desta matriz ao adicionar uma nova linha:

m_total_rows++;
ArrayResize(m_células,m_total_linhas*m_total_colunas,10000);

- para cada um dos 36 milhões de células de linha, você tem que encontrar um pedaço de memória livre por tempo suficiente, agarrá-lo, copiar o valor para um novo local, e soletrar o comprimento. O fato de que 10 mil elementos (ou bytes, não me lembro) mais memória é alocada não importa: quando mais uma fileira vier, m_total_rows aumentará novamente, m_total_rows*m_total_colunas também, e novamente a memória para a matriz será realocada através de cópia. Esta é a razão da lentidão do roteiro.

Obrigado pela análise do código.

Estou tendo dificuldade para entender o OOP, então fazer edições é uma tortura para mim. Como entendi é sobre a classe, que é responsável pela leitura, é onde todo o arquivo é dividido em matrizes de string, e só então, se eu quiser, converto estes valores de string para outro tipo e os coloco em matrizes de tipo int no meu script. Se eu entender corretamente, então para acelerar o processo, devo ler o arquivo inteiro e descobrir quantas linhas e colunas existem e quantos símbolos estão em cada célula, e então selecionar imediatamente o tamanho da matriz? Então, como podemos fazer isso?

Vladimir:

A memória é alocada em pedaços múltiplos de 8 bytes, mesmo para sistemas operacionais de 32 bits. Podemos supor que m_cells ocupará 1 Gb, não (400 + 78) Mb. Para cada cópia, precisamos de tanto mais espaço de memória quanto m_cells já ocupa, a duplicação da memória ocuparia 2 GB de memória. Em vez dos 78 MB que contêm as informações reais.

Em resumo, uma forma muito ineficiente de armazenar em células de corda. É difícil ser mais específico sem conhecer a tarefa.

Eu gostaria de entender de onde vêm 400 megabytes de uma só vez? Eu entendi corretamente que a memória é alocada, mas não é apagada/alargada a memória alocada anteriormente?

Aleksey Vyazmikin  
Konstantin Erin:
Tente jogar fora ArraySize() e ArrayResize() - você sabe o tamanho. Tomar 2 vezes maior só para o caso de... Informe-me o resultado

De onde despejar de um roteiro ou classe? O tamanho é conhecido, já que eu sei o tamanho do arquivo? Mas, o arquivo pode ter um tamanho diferente, o roteiro não é feito de uma só vez.

Razão: