至少要把代码放在MQL中...你必须逐行计算。
SQL、Apache Spark或其他变体被用于此类任务。
至少要把代码放在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 ); } }我附上了整个脚本。
我有一个问题,我的CSV文件大小为78兆,我想计算它,因为Excel的大小非常慢,我想用MT5。
我做了一个脚本,只把每一行的数据读入数组(57个数组用于从文件中读取,57个数组用于写入新文件),数组的大小等于CSV文件的行数。因此,该脚本占用了8G的内存,而Excel的内存不到1.5G,读/写操作花了MT5多达9分钟!
你有600 000个字符串,每个字符串最多包含57个单元,这些单元被读入一维数组string m_cells[]; 这就是数组中的3600万个字符串元素。我记得,字符串 类型,即使是空字符串也需要12个字节。仅仅是服务(地址、字符串长度)信息就有400MB,即使所有单元格都是空的。看看当你添加一个新的行时,对这个数组做一个调整会发生什么。
m_total_rows++;
ArrayResize(m_cells,m_total_rows*m_total_columns,10000)。
- 对于3600万个行单元中的每一个,你必须找到一块足够长的空闲内存,抓住它,将其值复制到一个新的位置,然后拼出长度。多分配一万个元素(或字节,我不记得了)的内存并不重要:当再来一行时,m_total_rows会再次增加,m_total_rows*m_total_columns也会增加,阵列的内存会再次通过复制重新分配。这就是为什么脚本需要这么长时间的原因。
即使是32位的操作系统,内存也是以8字节的块状分配的。我们可以假设m_cells不是(400+78)MB,而是1Gb。对于每个副本,我们需要的内存空间与m_cells已经占据的空间一样多,增加一倍的内存会占用2GB的内存。而不是78MB,其中包含实际信息。
总而言之,这是一种非常低效的字符串单元存储方式。在不了解任务的情况下,很难说得更具体。
试着取消函数ArraySize() 和ArrayResize()--你知道大小。为了安全起见,可服用2倍的量。报告结果
我有一个问题,我的CSV文件大小为78兆,我想计算它,因为Excel的大小很慢,我在想使用MT5。
我做了一个脚本,只把每一行的数据读入数组(57个数组用于从文件中读取,57个数组用于写入新文件),数组的大小等于CSV文件的行数。因此,该脚本占用了8G的内存,而Excel的内存不到1.5G,读/写操作花了MT5多达9分钟!
我曾经遇到过这个问题。做了很多修复工作。不记得整个事情了--那是一个一次性的工作。
但尝试设置ArrayResize(arrRead_01,arrSize); 3参数
|
实验。
你有60万个字符串,每个字符串最多包含57个单元,它们被读入一个一维字符串数组string m_cells[]; 也就是说,数组中有3600万个字符串元素。我记得,字符串 类型,即使是空字符串也需要12个字节。仅仅是服务(地址、字符串长度)信息就有400MB,即使所有单元格都是空的。看看当你增加一行新的时候,对这个数组做一个调整会发生什么。
m_total_rows++;
ArrayResize(m_cells,m_total_rows*m_total_columns,10000)。
- 对于3600万个行单元中的每一个,你必须找到一块足够长的空闲内存,抓住它,将其值复制到一个新的位置,然后拼出长度。多分配一万个元素(或字节,我不记得了)的内存并不重要:当再来一行时,m_total_rows会再次增加,m_total_rows*m_total_columns也会增加,阵列的内存会再次通过复制重新分配。这就是脚本缓慢的原因。
谢谢你的代码分析。
我很难理解OOP,所以对它进行编辑对我来说是一种折磨。按照我的理解,这是关于类的问题,它负责读取,就是把整个文件分割成字符串数组,只有这样,如果我想的话,我把这些字符串值转换成另一种类型,并把它们放到我的脚本中的int类型的数组中。如果我理解正确的话,那么为了加快进程,我应该读取整个文件,弄清楚有多少行和列,每个单元格有多少个符号,然后立即选择数组大小?那么我们如何才能做到这一点呢?
即使是32位的操作系统,内存也是以8字节的块状分配的。我们可以假设m_cells将占用1Gb,而不是(400+78)Mb。对于每个副本,我们需要的内存空间与m_cells已经占据的空间一样多,增加一倍的内存会占用2GB的内存。而不是包含实际信息的78MB。
总而言之,这是一种非常低效的字符串单元存储方式。在不了解任务的情况下,很难说得更具体。
我想了解一下,400兆字节是怎么一下子就出来的?我是否正确理解了内存被分配,但没有清除/释放先前分配的内存?
我有一个问题,我的CSV文件大小为78兆,我想计算它,因为Excel的大小很慢,我在想使用MT5。
我做了一个脚本,只为每一行读取数据到数组(57个数组用于从文件中读取,57个数组用于写入新文件),数组的大小 等于CSV文件的行数。因此,该脚本占用了8千兆字节的内存,而Excel不到1.5千兆字节,读/写操作花了MT5 9分钟之多