MT5 RAM의 메모리 폭식, 대용량 파일 읽기/쓰기 문제

 

제 질문입니다. 78MB 크기의 CSV 파일이 있는데 엑셀이 크기 때문에 너무 어리둥절해서 MT5를 사용하려고 생각해서 줄여서 쓰고 싶습니다.

지금까지 각 행(파일에서 읽기용 57개 배열, 새 파일 쓰기용 57개)의 배열로 데이터를 읽는 스크립트를 만들었습니다. 배열 의 크기는 CSV 파일의 행 수와 같습니다. 그래서 스크립트는 8기가 바이트의 메모리를 먹었고 엑셀은 1.5기가 미만이었고 MT5 읽기/쓰기 작업은 9분이나 수행했습니다!

 

최소한 MQL의 코드가 게시되었습니다... 한 줄씩 계산해야 합니다.

이러한 작업에는 SQL, Apache Spark 또는 기타 옵션이 사용됩니다.

 
Roffild :

최소한 MQL의 코드가 게시되었습니다... 한 줄씩 계산해야 합니다.

이러한 작업에는 SQL, Apache Spark 또는 기타 옵션이 사용됩니다.

아직 계산이 없습니다. 알 수 없는 이유로 배열에 쓰는 데 너무 많은 시간이 걸린다는 것뿐입니다(사실, 시간을 잡아먹는 파일에서 읽는 중이고 메모리에 대해 아직 명확하지 않음).

나는 코드에 문제가 있다는 것을 배제하지 않는다. 나는 MT4와 함께 (규칙과 같은) 조정된 읽기 수업을 사용하고 있습니다.

주요 코드는 거의 700줄입니다. 흥미로운 것은 없습니다. 우리는 배열을 선언하고, 배열 을 재설정하고, 배열의 크기를 변경하고, 파일에서 배열로 데이터를 쓰고, 배열에서 배열로 데이터를 덮어쓰고, 다음에서 데이터를 씁니다. 파일에 대한 배열.

돈을 지불한 수업은 다음과 같습니다.

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

제거된 버전의 스크립트(읽기에 문제가 있으므로 레코드 제거됨)

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

  }
//+------------------------------------------------------------------+
파일:
 

문제가 하나 더 있습니다. 48개 이상의 열을 작성하는 방법을 알 수 없습니다. 수업도 이용합니다. 레코드의 열 수를 확장하기 위해 클래스를 수정하는 데 도움을 줄 수 있는 사람이 있습니까?

다음은 이전 게시물에서 누락된 코드 입니다 .

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

하지만 파일에 데이터를 쓰기 위한 클래스도 유료

 //+------------------------------------------------------------------+
//|                                                    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 );
     }
  }  
전체 스크립트를 첨부했습니다.
파일:
 

78MB - 확실히 약 1,000,000줄이 있습니다.

먼저 전체 파일이 메모리에 복사됩니다. 그런 다음 int(8바이트) 유형의 배열 4개에 행 수를 곱합니다. 물론 RAM은 빨리 소진됩니다.

대용량 파일을 작업하기 위해서는 읽기와 쓰기가 섹터별로 이루어져야 하며, 여기서는 불필요한 메모리도 해제되지 않습니다.
 
Roffild :

78MB - 확실히 약 1,000,000줄이 있습니다.

먼저 전체 파일이 메모리에 복사됩니다. 그런 다음 int(8바이트) 유형의 배열 4개에 행 수를 곱합니다. 물론 RAM은 빨리 소진됩니다.

대용량 파일을 작업하기 위해서는 읽기와 쓰기가 섹터별로 이루어져야 하며, 여기서는 불필요한 메모리도 해제되지 않습니다.

파일 606004의 줄.

Excel에서 데이터를 메모리에 복사하지 않는 한?

다른 방식으로 파일 작업을 구성해야 할 수도 있습니다. 파일에서 데이터를 읽는 데 가장 많은 시간이 소요됩니다. 왜 그런지 모르겠습니다.

추가 작업을 위해 메모리에 전체 배열이 필요합니다. 그렇지 않으면 읽기/쓰기에 훨씬 더 많은 시간을 할애하게 됩니다.

 
Aleksey Vyazmikin :

제 질문입니다. 78MB 크기의 CSV 파일이 있는데 엑셀이 크기 때문에 너무 어리둥절해서 MT5를 사용하려고 생각해서 줄여서 쓰고 싶습니다.

지금까지 각 행(파일에서 읽기용 57개 배열, 새 파일 쓰기용 57개)의 배열로 데이터를 읽는 스크립트를 만들었습니다. 배열의 크기는 CSV 파일의 행 수와 같습니다. 그래서 스크립트는 8기가 바이트의 메모리를 먹었고 엑셀은 1.5기가 미만이었고 MT5 읽기/쓰기 작업은 9분이나 수행했습니다!

각각 최대 57개의 셀을 포함하는 600,000개의 행이 있습니다. 이 행은 문자열 m_cells[]의 1차원 배열로 읽혀집니다. 그것은 배열의 3600만 문자열 요소입니다. 문자열 유형은 빈 문자열의 경우에도 12바이트를 사용합니다. 이것은 모든 셀이 비어 있는 경우에도 400MB의 서비스 전용(주소, 행 길이 ) 정보입니다. 한 줄을 새로 추가하는 동안 이 배열의 크기를 조정하면 어떻게 되는지 확인하세요.

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

- 3600만 행 셀 각각에 대해 충분히 긴 여유 메모리 조각을 찾아서 잡고, 값을 새 위치에 복사하고, 길이를 설정해야 합니다. 메모리가 또 다른 10,000개 요소(또는 바이트, 기억나지 않음)에 할당된다는 사실은 역할을 하지 않습니다. 다른 행이 도착하면 m_total_rows가 다시 증가하고 m_total_rows * m_total_columns도 증가하고 다시 어레이용 메모리가 복사와 함께 재할당됩니다. 이것이 스크립트 지속 시간의 이유입니다.

메모리는 32비트 운영 체제의 경우에도 길이가 8바이트의 배수인 청크로 할당됩니다. m_cells에서는 (400 + 78) MB가 아니라 1GB가 필요하다고 가정할 수 있습니다. 각 복사본에 대해 m_cells가 이미 사용 중인 것과 동일한 양의 메모리 공간이 필요하며 메모리를 두 배로 늘리려면 2GB의 메모리가 필요합니다. 실제 정보를 포함하는 78MB 대신.

일반적으로 문자열 셀에 저장하는 매우 비효율적인 방법입니다. 문제를 모르면 더 구체적으로 말씀드리기 어렵습니다.

 
ArraySize()ArrayResize() 함수를 버리십시오. 결국 크기를 알고 있습니다. 만일을 대비하여 2배 더 복용... 결과보고
 
Konstantin Erin :
ArraySize() 및 ArrayResize() 함수를 버리십시오. 결국 크기를 알고 있습니다. 만일을 대비하여 2배 더 복용... 결과보고
알렉세이 비아즈미킨 :

제 질문입니다. 78MB 크기의 CSV 파일이 있는데 엑셀이 크기 때문에 너무 어리둥절해서 MT5를 사용하려고 생각해서 줄여서 쓰고 싶습니다.

지금까지 각 행(파일에서 읽기용 57개 배열, 새 파일 쓰기용 57개)의 배열로 데이터를 읽는 스크립트를 만들었습니다. 배열의 크기는 CSV 파일의 행 수와 같습니다. 그래서 스크립트는 8기가 바이트의 메모리를 먹었고 엑셀은 1.5기가 미만이었고 MT5 읽기/쓰기 작업은 9분이나 수행했습니다!


한 번 그런 문제에 직면했습니다. 많은 수정을 했습니다. 나는 모든 것을 기억하지 못합니다. 그것은 일회성 작업이었습니다.

하지만 여기서 ArrayResize (arrRead_01,arrSize)를 설정해 보십시오. 세 번째 매개변수


    정수      Reserve_size=0          // 예약 크기 값(초과)


실험.

 
Vladimir :

각각 최대 57개의 셀을 포함하는 600,000개의 행이 있습니다. 이 행은 문자열 m_cells[]의 1차원 배열로 읽혀집니다. 그것은 배열의 3600만 문자열 요소입니다. 문자열 유형은 빈 문자열의 경우에도 12바이트를 사용합니다. 이것은 모든 셀이 비어 있는 경우에도 400MB의 서비스 전용(주소, 행 길이 ) 정보입니다. 한 줄을 새로 추가하는 동안 이 배열의 크기를 조정하면 어떻게 되는지 확인하세요.

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

- 3,600만 개의 셀 문자열 각각에 대해 충분히 긴 여유 메모리 조각을 찾아서 가져와 값을 새 위치에 복사하고 길이를 설정해야 합니다. 메모리가 다른 10,000개 요소(또는 바이트, 기억나지 않음)에 할당되었다는 사실은 중요하지 않습니다. 다른 행이 도착하면 m_total_rows가 다시 증가하고 m_total_rows * m_total_columns도 다시 증가하고 배열의 메모리는 다시 증가합니다. - 복사와 함께 할당됩니다. 이것이 스크립트 지속 시간의 이유입니다.

코드 분석 감사합니다.

나는 OOP를 매우 어렵게 이해하므로 변경하는 것이 나에게 고통입니다. 내가 알기로 요점은 읽기를 담당하는 클래스에 있으며 전체 파일이 거기에서 문자열 배열로 분할되고 그 다음에야 내 요청에 따라 이러한 문자열 값을 다른 유형으로 변환하고 내 스크립트에서 int 유형의 배열에 넣습니다. 내가 올바르게 이해했다면 프로세스 속도를 높이려면 전체 파일을 읽고 총 행과 열이 몇 개인지, 이러한 각 셀에 몇 개의 문자가 있는지 이해하고 해당 배열의 크기를 이미 선택해야 합니다. 떨어져 있는? 그럼 어떻게 할까요?

블라디미르 :

메모리는 32비트 운영 체제의 경우에도 길이가 8바이트의 배수인 청크로 할당됩니다. m_cells에서는 (400 + 78) MB가 아니라 1GB가 필요하다고 가정할 수 있습니다. 각 복사본에 대해 m_cells가 이미 사용 중인 것과 동일한 양의 메모리 공간이 필요하며 메모리를 두 배로 늘리려면 2GB의 메모리가 필요합니다. 실제 정보를 포함하는 78MB 대신.

일반적으로 문자열 셀에 저장하는 매우 비효율적인 방법입니다. 문제를 모르면 더 구체적으로 말씀드리기 어렵습니다.

400메가바이트가 어디서 오는지 바로 알고 싶습니다. 메모리가 할당되어 있다는 것을 정확히 이해했는데 이전에 할당된 메모리가 지워지지 않거나 버려지는 건가요?

 
Konstantin Erin :
ArraySize() 및 ArrayResize() 함수를 버리십시오. 결국 크기를 알고 있습니다. 만일을 대비하여 2배 더 복용... 결과보고

스크립트 또는 클래스에서 버릴 곳은 어디입니까? 파일 크기를 알기 때문에 크기를 알 수 있습니까? 하지만 파일의 크기가 다를 수 있고, 스크립트가 한번에 만들어지지는 않습니다...