Voracidad de la memoria RAM de la MT5, problemas con la lectura/escritura de archivos grandes
Al menos pon el código en MQL... Hay que contar línea por línea.
Para estas tareas se utilizan SQL, Apache Spark u otras variantes.
Al menos pon el código en MQL ... Hay que calcular línea por línea.
Para este tipo de tareas y utiliza SQL, Apache Spark u otras opciones.
Todavía no tengo cálculos ahí, es que escribir en el array lleva mucho tiempo por razones desconocidas (en realidad, es la lectura del archivo lo que se come el tiempo, no está claro lo de la memoria todavía).
No descarto un problema con el código. Estoy usando la clase de lectura, ajustada (un poco de reglas) de MT4.
El código principal tiene casi 700 líneas - nada interesante allí - declaramos el array, ponemos el array a cero, cambiamos el tamaño del array, escribimos datos en el array desde el archivo, sobrescribimos datos del array en el array, escribimos datos del array en el archivo.
Aquí está la clase que se pagó:
//+------------------------------------------------------------------+ //| 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); } //+------------------------------------------------------------------+
El guión (se omite la escritura, porque el problema está en la lectura) es una versión reducida.
#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]; } } //+------------------------------------------------------------------+
Hay un problema más: no sé cómo escribir más de 48 columnas. También uso la clase. ¿Alguien puede ayudar a corregir la clase para expandir el número de columnas para el registro?
Aquí está el código que falta en la publicación anterior para escribir en un archivo .
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]) ); }
Pero también se paga la clase por escribir datos en un archivo.
//+------------------------------------------------------------------+ //| 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 ); } }Adjunto el guión completo.
78 Mbytes - debe haber alrededor de 1.000.000 de líneas.
Primero se copia todo el archivo en la memoria. Luego 4 matrices de tipo int (8 bytes) multiplicadas por el número de líneas. Por supuesto, la RAM se agotará rápidamente.
Para trabajar con archivos de gran tamaño, la lectura y la escritura deben realizarse sector por sector, y aquí no se libera ni siquiera la memoria innecesaria.78 Mbytes - debe haber alrededor de 1.000.000 de líneas.
Primero se copia todo el archivo en la memoria. Luego 4 matrices de tipo int (8 bytes) multiplicadas por el número de líneas. Por supuesto, la RAM se agotará rápidamente.
Para trabajar con archivos grandes necesito leer y escribir sector por sector, pero aquí no se libera ni siquiera la memoria innecesaria.Hay 606004 líneas en el archivo.
¿Exlle no copia los datos en la memoria?
Tal vez habría que manejar el archivo de alguna otra manera, ya que la mayor parte del tiempo se gasta en leer datos del archivo y no entiendo por qué es así.
Necesito una matriz completa en la memoria para seguir trabajando, de lo contrario paso mucho más tiempo para leer/escribir.
Tengo una pregunta, mi archivo CSV tiene un tamaño de 78 megabytes, quiero calcularlo, como Excel es muy lento por su tamaño, estaba pensando en usar MT5.
Hice un script que sólo lee los datos en arrays para cada línea (57 arrays para leer del archivo y 57 para escribir en el nuevo archivo), el tamaño del array es igual al número de líneas en el archivo CSV. ¡Así, el script se comió 8 Gbytes de memoria, mientras que Excel tenía menos de 1,5 Gbytes, y la operación de lectura/escritura le llevó a MT5 hasta 9 minutos!
Tiene 600 000 cadenas, cada una de las cuales contiene hasta 57 celdas que se leen en una matriz unidimensional cadena m_células[]; Eso es 36 millones de elementos de cadena en la matriz. El tipo de cadena, según recuerdo, toma 12 bytes incluso para una cadena vacía. Son 400 MB de información de servicio (direcciones, longitudes de cadena) solamente, incluso si todas las celdas están vacías. Vea lo que ocurre cuando se redimensiona esta matriz al añadir una nueva fila:
m_total_rows++;
ArrayResize(m_cells,m_total_rows*m_total_columns,10000);
- para cada uno de los 36 millones de celdas de fila, hay que encontrar un trozo de memoria libre lo suficientemente largo, cogerlo, copiar el valor a una nueva ubicación y deletrear la longitud. El hecho de que se asignen 10 mil elementos (o bytes, no lo recuerdo) más de memoria no importa: cuando llegue una fila más, m_total_rows volverá a aumentar, m_total_rows*m_total_columnas también, y de nuevo se reasignará memoria para el array copiando. Esta es la razón por la que el guión tarda tanto.
La memoria se asigna en trozos múltiples de 8 bytes, incluso en los sistemas operativos de 32 bits. Podemos suponer que m_cells no es (400 + 78) MB, sino 1 Gb. Para cada copia, necesitamos tanto espacio de memoria como el que ya ocupa m_cells, duplicando la memoria ocuparía 2 GB de memoria. En lugar de 78 MB, que contiene la información real.
En definitiva, es una forma muy ineficiente de almacenar en celdas de cadena. Es difícil ser más específico sin conocer la tarea.
Trate de eliminar las funciones ArraySize() y ArrayResize() - usted sabe el tamaño. Para estar seguro, tome dos veces más. Resultados del informe
Tengo una pregunta, mi archivo CSV tiene un tamaño de 78 megabytes, quiero calcularlo, como Excel es muy lento por su tamaño, estaba pensando en usar MT5.
Hice un script que sólo lee los datos en arrays para cada línea (57 arrays para leer del archivo y 57 para escribir en el nuevo archivo), el tamaño del array es igual al número de líneas en el archivo CSV. Así, el script se comió 8 Gbytes de memoria, mientras que Excel tenía menos de 1,5 Gbytes, y la operación de lectura/escritura le llevó a MT5 hasta 9 minutos.
Una vez tuve este problema. Hizo un montón de arreglos. No puedo recordar todo, fue un trabajo único,
pero intenta establecerArrayResize(arrRead_01,arrSize); 3 parámetro
|
Experimento.
Tiene 600 mil cadenas, cada una de las cuales contiene hasta 57 celdas, que se leen en un array unidimensional cadena m_células[]; Es decir, 36 millones de elementos de cadena en el array. El tipo de cadena, según recuerdo, toma 12 bytes incluso para una cadena vacía. Son 400 MB de información de servicio (direcciones, longitudes de cadena) solamente, incluso si todas las celdas están vacías. Vea lo que ocurre cuando se redimensiona esta matriz al añadir una nueva fila:
m_total_rows++;
ArrayResize(m_cells,m_total_rows*m_total_columns,10000);
- para cada uno de los 36 millones de celdas de fila, hay que encontrar un trozo de memoria libre lo suficientemente largo, cogerlo, copiar el valor a una nueva ubicación y deletrear la longitud. El hecho de que se asignen 10 mil elementos (o bytes, no lo recuerdo) más de memoria no importa: cuando llegue una fila más, m_total_rows volverá a aumentar, m_total_rows*m_total_columnas también, y de nuevo se reasignará memoria para el array mediante copia. Esta es la razón de la lentitud del script.
Gracias por el análisis del código.
Me cuesta entender la POO, así que hacer ediciones en ella es una tortura para mí. Según entendí se trata de la clase, que se encarga de la lectura, ahí es donde se divide todo el archivo en arrays de cadenas, y solo entonces, si quiero, convierto estos valores de cadena a otro tipo y los pongo en arrays de tipo int en mi script. Si lo he entendido bien, para acelerar el proceso, debería leer todo el archivo y averiguar cuántas filas y columnas hay y cuántos símbolos hay en cada celda, y luego seleccionar inmediatamente el tamaño del array? Entonces, ¿cómo podemos hacerlo?
La memoria se asigna en trozos múltiplos de 8 bytes, incluso en los sistemas operativos de 32 bits. Podemos suponer que m_cells ocupará 1 Gb, no (400 + 78) Mb. Para cada copia, necesitamos tanto espacio de memoria como el que ya ocupa m_cells, duplicando la memoria ocuparía 2 GB de memoria. En lugar de los 78 MB que contiene la información real.
En definitiva, una forma muy ineficiente de almacenar en celdas de cadena. Es difícil ser más específico sin conocer la tarea.
Me gustaría entender de dónde salen 400 megabytes de golpe. ¿He entendido bien que la memoria se asigna, pero no se borra/libera la memoria previamente asignada?
Intenta lanzar ArraySize() y ArrayResize(), ya sabes el tamaño. Toma 2 veces más grande por si acaso... Hazme saber el resultado
¿Desde dónde volcar desde un script o clase? El tamaño es conocido, ya que conozco el tamaño del archivo? Pero, el archivo puede tener un tamaño diferente, el script no se hace a la vez...
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
Tengo una pregunta, mi archivo CSV tiene un tamaño de 78 megabytes, quiero calcularlo, como Excel es muy lento por su tamaño, estaba pensando en usar MT5.
Hice un script que sólo lee los datos en arrays para cada línea (57 arrays para leer del archivo y 57 para escribir en el nuevo archivo), el tamaño del array es igual al número de líneas en el archivo CSV. Así, el script se comió 8 gigabytes de memoria, mientras que Excel tiene menos de 1,5 gigabytes, y la operación de lectura/escritura llevó a MT5 hasta 9 minutos.