voracità della memoria RAM di MT5, problemi con la lettura/scrittura di file di grandi dimensioni

Aleksey Vyazmikin  

Ho una domanda, il mio file CSV è grande 78 megabyte, voglio calcolarlo, poiché Excel è molto lento a causa delle sue dimensioni, stavo pensando di usare MT5.

Ho fatto uno script che legge solo i dati negli array per ogni riga (57 array per leggere dal file e 57 per scrivere nel nuovo file), la dimensione dell'array è uguale al numero di righe del file CSV. Così, lo script ha mangiato 8 gigabyte di memoria, mentre Excel è meno di 1,5 gigabyte, e l'operazione di lettura/scrittura ha richiesto a MT5 ben 9 minuti!

Roffild  

Almeno metti il codice in MQL... Bisogna contare riga per riga.

SQL, Apache Spark o altre varianti sono utilizzate per tali compiti.

Aleksey Vyazmikin  
Roffild:

Almeno mettere il codice in MQL ... Linea per linea dovrebbe essere calcolata.

Per tali compiti e utilizza SQL, Apache Spark o altre opzioni.

Non ho ancora dei calcoli lì, è solo che scrivere nell'array richiede così tanto tempo per ragioni sconosciute (in realtà, è la lettura dal file che consuma il tempo, non è ancora chiara la memoria).

Non escludo un problema con il codice. Sto usando la classe di lettura, modificata (un po' di regole) da MT4.

Il codice principale è di quasi 700 righe - niente di interessante - dichiariamo l'array, azzeriamo l'array, cambiamo la dimensione dell'array, scriviamo i dati nell'array dal file, sovrascriviamo i dati dall'array all'array, scriviamo i dati dall'array al file.

Ecco la classe per la quale è stato pagato il denaro:

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

Lo script (la scrittura è omessa, perché il problema è la lettura) è una versione tagliata.

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

  }
//+------------------------------------------------------------------+
File:
Aleksey Vyazmikin  

C'è un altro problema: non riesco a capire come scrivere più di 48 colonne. Uso anche la classe. Qualcuno può aiutare a correggere la classe per espandere il numero di colonne per il record?

Ecco il codice che manca nel post precedente perscrivere in un .

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

Ma viene pagata anche la classe per scrivere dati su un file

 //+------------------------------------------------------------------+
//|                                                    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 );
     }
  }  
Ho allegato l'intero script.
File:
Roffild  

78 Mbyte - ci devono essere circa 1.000.000 di linee lì dentro.

Prima l'intero file viene copiato in memoria. Poi 4 array di tipo int (8 byte) moltiplicati per il numero di linee. Naturalmente, la RAM si esaurirà rapidamente.

Per lavorare con file di grandi dimensioni, la lettura e la scrittura dovrebbero essere fatte settore per settore, e qui anche la memoria non necessaria non viene liberata.
Aleksey Vyazmikin  
Roffild:

78 Mbyte - ci devono essere circa 1.000.000 di linee.

Prima l'intero file viene copiato in memoria. Poi 4 array di tipo int (8 byte) moltiplicati per il numero di linee. Naturalmente, la RAM si esaurirà rapidamente.

Per lavorare con grandi file ho bisogno di leggere e scrivere settore per settore e qui anche la memoria inutile non viene liberata.

Ci sono 606004 linee nel file.

Exlle non copia i dati in memoria?

Forse dovremmo gestire il file in qualche altro modo, dato che la maggior parte del tempo viene speso per leggere i dati dal file e non capisco perché sia così.

Ho bisogno di un array completo in memoria per un ulteriore lavoro, altrimenti spendo molto più tempo per leggere/scrivere.

Vladimir  
Aleksey Vyazmikin:

Ho una domanda, il mio file CSV è grande 78 megabyte, voglio calcolarlo, poiché Excel è molto lento a causa delle sue dimensioni, stavo pensando di usare MT5.

Ho fatto uno script che legge solo i dati negli array per ogni riga (57 array per leggere dal file e 57 per scrivere nel nuovo file), la dimensione dell'array è uguale al numero di righe del file CSV. Così, lo script mangiava 8 Gbyte di memoria, mentre Excel era meno di 1,5 Gbyte, e l'operazione di lettura/scrittura richiedeva a MT5 ben 9 minuti!

Avete 600 000 stringhe, ognuna contenente fino a 57 celle che vengono lette in un array unidimensionale string m_cells[]; Questo è 36 milioni di elementi di stringa nell'array. Il tipo stringa, ricordo, prende 12 byte anche per una stringa vuota. Sono 400 MB di sole informazioni di servizio (indirizzi, lunghezze di stringhe), anche se tutte le celle sono vuote. Guarda cosa succede quando fai un ridimensionamento di questo array quando aggiungi una nuova riga:

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

- per ognuno dei 36 milioni di celle di fila, bisogna trovare un pezzo di memoria libera abbastanza lungo, afferrarlo, copiare il valore in una nuova posizione e scrivere la lunghezza. Il fatto che 10 mila elementi (o byte, non ricordo) in più di memoria siano allocati non importa: quando arriva un'altra riga, m_total_rows aumenterà di nuovo, m_total_rows*m_total_columns anche, e di nuovo la memoria per l'array sarà riallocata copiando. Questo è il motivo per cui lo script richiede così tanto tempo.

La memoria è allocata in chunks multipli di 8 byte anche per i sistemi operativi a 32 bit. Possiamo supporre che m_cellule non sia (400 + 78) MB, ma 1 Gb. Per ogni copia, abbiamo bisogno di tanto spazio di memoria quanto m_cells occupa già, raddoppiando la memoria occuperebbe 2 GB di memoria. Invece di 78 MB, che contiene le informazioni effettive.

Tutto sommato, è un modo molto inefficiente di immagazzinare in celle di stringa. È difficile essere più specifici senza conoscere il compito.

Konstantin Erin  
Provate a buttare fuori ArraySize() e ArrayResize() - conoscete le dimensioni. Prendete il doppio della taglia, non si sa mai... Fammi sapere il risultato
Vladislav Andruschenko  
Konstantin Erin:
Provate ad eliminare le funzioni ArraySize() e ArrayResize() - conoscete le dimensioni. Per andare sul sicuro, prendine 2 volte tanto. Risultati del rapporto
Aleksey Vyazmikin:

Ho una domanda, il mio file CSV è grande 78 megabyte, voglio calcolarlo, poiché Excel è molto lento a causa delle sue dimensioni, stavo pensando di usare MT5.

Ho fatto uno script che legge solo i dati negli array per ogni riga (57 array per leggere dal file e 57 per scrivere nel nuovo file), la dimensione dell'array è uguale al numero di righe del file CSV. Così, lo script mangiava 8 Gbyte di memoria, mentre Excel era meno di 1,5 Gbyte, e l'operazione di lettura/scrittura richiedeva a MT5 ben 9 minuti!


Ho avuto questo problema una volta. Ha fatto molte correzioni. Non riesco a ricordare il tutto - è stato un lavoro una tantum,

ma prova a impostareArrayResize(arrRead_01,arrSize); 3 parametro


intreserve_size=0// valore della dimensione della riserva (in eccesso )


Esperimento.

Aleksey Vyazmikin  
Vladimir:

Avete 600 mila stringhe, ognuna contenente fino a 57 celle, che vengono lette in un array di stringhe unidimensionale string m_cells[]; cioè 36 milioni di elementi di stringa nell'array. Il tipo stringa, ricordo, prende 12 byte anche per una stringa vuota. Sono 400 MB di sole informazioni di servizio (indirizzi, lunghezze di stringhe), anche se tutte le celle sono vuote. Guarda cosa succede quando fai un ridimensionamento di questo array quando aggiungi una nuova riga:

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

- per ognuno dei 36 milioni di celle di fila, bisogna trovare un pezzo di memoria libera abbastanza lungo, afferrarlo, copiare il valore in una nuova posizione e scrivere la lunghezza. Il fatto che 10 mila elementi (o byte, non ricordo) in più di memoria siano allocati non importa: quando arriva un'altra riga, m_total_rows aumenterà di nuovo, m_total_rows*m_total_columns anche, e di nuovo la memoria per l'array sarà riallocata copiando. Questa è la ragione della lentezza dello script.

Grazie per l'analisi del codice.

Faccio fatica a capire l'OOP, quindi fare delle modifiche è una tortura per me. Come ho capito si tratta della classe, che è responsabile della lettura, è lì che l'intero file viene diviso in array di stringhe, e solo allora, se voglio, converto questi valori di stringa in un altro tipo e li metto in array di tipo int nel mio script. Se ho capito bene, allora per accelerare il processo, dovrei leggere l'intero file e capire quante righe e colonne ci sono e quanti simboli ci sono in ogni cella, e poi selezionare immediatamente la dimensione dell'array? Allora come possiamo farlo?

Vladimir:

La memoria è allocata in chunks multipli di 8 byte anche per i sistemi operativi a 32 bit. Possiamo supporre che m_cellule occupino 1 Gb, non (400 + 78) Mb. Per ogni copia, abbiamo bisogno di tanto spazio di memoria quanto m_cells occupa già, raddoppiando la memoria occuperebbe 2 GB di memoria. Invece dei 78 MB che contengono le informazioni effettive.

Tutto sommato, un modo molto inefficiente di immagazzinare in celle di stringa. È difficile essere più specifici senza conoscere il compito.

Vorrei capire da dove vengono 400 megabyte tutti insieme? Ho capito bene che la memoria viene allocata, ma non viene cancellata/rilasciata la memoria precedentemente allocata?

Aleksey Vyazmikin  
Konstantin Erin:
Provate a buttare fuori ArraySize() e ArrayResize() - conoscete le dimensioni. Prendi 2 volte più grande, per sicurezza... Fammi sapere il risultato

Da dove scaricare da uno script o da una classe? La dimensione è nota, dato che conosco la dimensione del file? Ma, il file può essere di dimensioni diverse, lo script non è fatto in una volta sola...

Motivazione: