Voracité de la mémoire RAM de MT5, problèmes de lecture/écriture de gros fichiers

 

J'ai une question, mon fichier CSV fait 78 mégaoctets, je veux le calculer, comme Excel est très lent à cause de sa taille, je pensais utiliser MT5.

J'ai créé un script qui lit uniquement les données dans des tableaux pour chaque ligne (57 tableaux pour la lecture du fichier et 57 pour l'écriture dans le nouveau fichier), la taille du tableau est égale au nombre de lignes du fichier CSV. Ainsi, le script a consommé 8 gigaoctets de mémoire, alors qu'Excel en consomme moins de 1,5 gigaoctet, et l'opération de lecture/écriture a pris à MT5 pas moins de 9 minutes !

 

Au moins, mettez le code dans MQL... Vous devez compter ligne par ligne.

SQL, Apache Spark ou d'autres variantes sont utilisés pour ces tâches.

 
Roffild:

Au moins, mettez le code dans MQL ... Il faut calculer ligne par ligne.

Pour de telles tâches et utilise SQL, Apache Spark ou d'autres options.

Je n'ai pas encore fait de calculs, c'est juste que l'écriture dans le tableau prend beaucoup de temps pour des raisons inconnues (en fait, c'est la lecture du fichier qui prend du temps, la mémoire n'est pas encore claire).

Je n'exclus pas un problème avec le code. J'utilise la classe de lecture, modifiée (règles en quelque sorte) à partir de MT4.

Le code principal fait presque 700 lignes - rien d'intéressant ici - nous déclarons le tableau, remettons le tableau à zéro, changeons la taille du tableau, écrivons des données dans le tableau à partir d'un fichier, écrasons les données du tableau dans le tableau, écrivons les données du tableau dans le fichier.

Voici le cours qui a été payé :

//+------------------------------------------------------------------+
//|                                                    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);
  }
//+------------------------------------------------------------------+

Le script (l'écriture est omise, car le problème se situe au niveau de la lecture) est une version coupée.

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

  }
//+------------------------------------------------------------------+
Dossiers :
 

Il y a un autre problème - je n'arrive pas à comprendre comment écrire plus de 48 colonnes. J'utilise aussi la classe. Quelqu'un peut-il aider à corriger la classe afin d'augmenter le nombre de colonnes pour l'enregistrement ?

Voici le code, qui manquait dans le post précédent, pour écrire dans un fichier .

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

Mais la classe d'écriture de données dans un fichier est également payante

 //+------------------------------------------------------------------+
//|                                                    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 );
     }
  }  
J'ai joint tout le script.
Dossiers :
 

78 Moctets - il doit y avoir environ 1 000 000 de lignes.

Tout d'abord, le fichier entier est copié en mémoire. Puis 4 tableaux de type int (8 octets) multipliés par le nombre de lignes. Bien sûr, la mémoire vive s'épuisera rapidement.

Pour travailler avec des fichiers volumineux, la lecture et l'écriture doivent se faire secteur par secteur, et ici, même la mémoire inutile n'est pas libérée.
 
Roffild:

78 Moctets - il doit y avoir environ 1 000 000 de lignes.

Tout d'abord, le fichier entier est copié en mémoire. Puis 4 tableaux de type int (8 octets) multipliés par le nombre de lignes. Bien sûr, la mémoire vive s'épuisera rapidement.

Pour travailler avec des fichiers volumineux, je dois lire et écrire secteur par secteur et ici, même la mémoire inutile n'est pas libérée.

Il y a 606004 lignes dans le fichier.

Est-ce qu'exlle ne copie pas les données en mémoire ?

Il faudrait peut-être gérer le fichier d'une autre manière, car la plupart du temps, on passe à lire les données du fichier et je ne comprends pas pourquoi il en est ainsi.

J'ai besoin d'un tableau complet en mémoire pour la suite du travail, sinon je passe beaucoup plus de temps en lecture/écriture.

 
Aleksey Vyazmikin:

J'ai une question, mon fichier CSV fait 78 mégaoctets, je veux le calculer, comme Excel est très lent à cause de sa taille, je pensais utiliser MT5.

J'ai créé un script qui lit uniquement les données dans des tableaux pour chaque ligne (57 tableaux pour la lecture du fichier et 57 pour l'écriture dans le nouveau fichier), la taille du tableau est égale au nombre de lignes du fichier CSV. Ainsi, le script a consommé 8 gigaoctets de mémoire, alors qu'Excel en consommait moins de 1,5 gigaoctet, et l'opération de lecture/écriture a pris à MT5 pas moins de 9 minutes !

Vous avez 600 000 chaînes, chacune contenant jusqu'à 57 cellules qui sont lues dans un tableau unidimensionnel string m_cells[] ; Cela représente 36 millions d'éléments de chaîne dans le tableau. Le type chaîne de caractères, je me souviens, prend 12 octets même pour une chaîne vide. Cela représente 400 Mo d'informations sur les services (adresses, longueurs de chaîne), même si toutes les cellules sont vides. Regardez ce qui se passe lorsque vous redimensionnez ce tableau en ajoutant une nouvelle ligne :

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

- pour chacune des 36 millions de cellules de ligne, il faut trouver un morceau de mémoire libre suffisamment long, le saisir, copier la valeur à un nouvel emplacement et épeler la longueur. Le fait que 10 000 éléments (ou octets, je ne me souviens plus) de mémoire supplémentaire soient alloués n'a pas d'importance : lorsqu'une ligne supplémentaire arrivera, m_total_rows augmentera à nouveau, m_total_rows*m_total_columns aussi, et la mémoire du tableau sera à nouveau réallouée par copie. C'est la raison pour laquelle le script est si long.

La mémoire est allouée par tranches multiples de 8 octets, même pour les systèmes d'exploitation 32 bits. Nous pouvons supposer que m_cells ne prend pas (400 + 78) MB mais 1 Gb. Pour chaque copie, nous avons besoin d'autant d'espace mémoire que m_cells en occupe déjà, un doublement de la mémoire occuperait 2 Go de mémoire. Au lieu de 78 MB, qui contient les informations réelles.

Dans l'ensemble, c'est une façon très inefficace de stocker dans des cellules de cordes. Il est difficile d'être plus précis sans connaître la tâche.

 
Essayez de jeter ArraySize() et ArrayResize() - vous connaissez la taille. Prenez le double de la taille, juste au cas où... Faites-moi savoir le résultat
 
Konstantin Erin:
Essayez d'éliminer les fonctions ArraySize() et ArrayResize() - vous connaissez la taille. Pour plus de sécurité, prenez deux fois plus. Résultats du rapport
Aleksey Vyazmikin:

J'ai une question, mon fichier CSV fait 78 mégaoctets, je veux le calculer, comme Excel est très lent à cause de sa taille, je pensais utiliser MT5.

J'ai créé un script qui lit uniquement les données dans des tableaux pour chaque ligne (57 tableaux pour la lecture du fichier et 57 pour l'écriture dans le nouveau fichier), la taille du tableau est égale au nombre de lignes du fichier CSV. Ainsi, le script a consommé 8 gigaoctets de mémoire, alors qu'Excel en consommait moins de 1,5 gigaoctet, et l'opération de lecture/écriture a pris à MT5 pas moins de 9 minutes !


J'ai eu ce problème une fois. J'ai fait beaucoup de réparations. Je ne me souviens pas de tout - c'était un travail ponctuel,

mais j'essaie de définirArrayResize(arrRead_01,arrSize); 3 paramètres


intreserve_size=0// valeur de la taille de la réserve (excès )


Expérimentation.

 
Vladimir:

Vous disposez de 600 000 chaînes, chacune contenant jusqu'à 57 cellules, qui sont lues dans un tableau de chaînes unidimensionnel string m_cells[] ; Soit 36 millions d'éléments de chaîne dans le tableau. Le type chaîne de caractères, je me souviens, prend 12 octets même pour une chaîne vide. Cela représente 400 Mo d'informations sur les services (adresses, longueurs de chaîne), même si toutes les cellules sont vides. Regardez ce qui se passe lorsque vous redimensionnez ce tableau en ajoutant une nouvelle ligne :

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

- pour chacune des 36 millions de cellules de ligne, il faut trouver un morceau de mémoire libre suffisamment long, le saisir, copier la valeur à un nouvel emplacement et épeler la longueur. Le fait que 10 000 éléments (ou octets, je ne me souviens plus) de mémoire supplémentaire soient alloués n'a pas d'importance : lorsqu'une ligne supplémentaire arrivera, m_total_rows augmentera à nouveau, m_total_rows*m_total_columns aussi, et la mémoire du tableau sera à nouveau réallouée par copie. C'est la raison de la lenteur du script.

Merci pour l'analyse du code.

J'ai du mal à comprendre la POO, donc y apporter des modifications est une torture pour moi. D'après ce que j'ai compris, il s'agit de la classe qui est responsable de la lecture, c'est là que le fichier entier est divisé en tableaux de chaînes de caractères, et seulement ensuite, si je veux, je convertis ces valeurs de chaînes de caractères en un autre type et les mets dans des tableaux de type int dans mon script. Si je comprends bien, pour accélérer le processus, je devrais lire le fichier entier et déterminer le nombre de lignes et de colonnes et le nombre de symboles dans chaque cellule, puis sélectionner immédiatement la taille du tableau ? Alors comment pouvons-nous faire ?

Vladimir:

La mémoire est allouée par tranches multiples de 8 octets, même pour les systèmes d'exploitation 32 bits. On peut supposer que les m_cellules occuperont 1 Gb, et non (400 + 78) Mb. Pour chaque copie, nous avons besoin d'autant d'espace mémoire que m_cells en occupe déjà, un doublement de la mémoire occuperait 2 Go de mémoire. Au lieu des 78 Mo qui contiennent les informations réelles.

Dans l'ensemble, c'est une façon très inefficace de stocker dans des cellules de cordes. Il est difficile d'être plus précis sans connaître la tâche.

J'aimerais comprendre d'où viennent ces 400 mégaoctets d'un coup ? Ai-je bien compris que la mémoire est allouée, mais pas effacée/libérée de la mémoire précédemment allouée ?

 
Konstantin Erin:
Essayez de jeter ArraySize() et ArrayResize() - vous connaissez la taille. Prenez-en deux fois plus, juste au cas où... Faites-moi savoir le résultat

D'où décharger un script ou une classe ? La taille est connue, puisque je connais la taille du fichier? Mais, le fichier peut avoir une taille différente, le script n'est pas fait en une seule fois...

Raison: