Setzen Sie den Code wenigstens in MQL... Sie müssen Zeile für Zeile zählen.
SQL, Apache Spark oder andere Varianten werden für solche Aufgaben verwendet.
Setzen Sie den Code wenigstens in MQL ... Es sollte Zeile für Zeile berechnet werden.
Für solche Aufgaben und verwendet SQL, Apache Spark oder andere Optionen.
Ich habe dort noch keine Berechnungen, es ist nur so, dass das Schreiben in das Array aus unbekannten Gründen so viel Zeit in Anspruch nimmt (eigentlich ist es das Lesen aus der Datei, das die Zeit verschlingt, es ist noch nicht klar, was mit dem Speicher passiert).
Ich schließe ein Problem mit dem Code nicht aus. Ich verwende die Leseklasse, die ich von MT4 übernommen habe (eine Art von Regeln).
Der Hauptcode besteht aus fast 700 Zeilen - nichts Interessantes - wir deklarieren Array, setzen Array auf Null zurück, ändern die Array-Größe, schreiben Daten aus der Datei in das Array, überschreiben Daten aus dem Array in das Array, schreiben Daten aus dem Array in die Datei.
Hier ist die Klasse, für die bezahlt wurde:
//+------------------------------------------------------------------+ //| 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); } //+------------------------------------------------------------------+
Das Skript (die Schrift wird weggelassen, da das Problem beim Lesen liegt) ist eine abgespeckte Version.
#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]; } } //+------------------------------------------------------------------+
Es gibt noch ein weiteres Problem - ich kann nicht herausfinden, wie ich mehr als 48 Spalten schreiben soll. Ich benutze die Klasse auch. Kann jemand helfen, die Klasse zu korrigieren, um die Anzahl der Spalten für den Datensatz zu erweitern?
Hier ist der Code, der im vorherigen Post fehlt, um in eine .
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]) ); }
Aber auch die Klasse zum Schreiben von Daten in eine Datei wird bezahlt
//+------------------------------------------------------------------+ //| 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 ); } }Ich habe das ganze Skript angehängt.
78 Mbyte - das sind etwa 1.000.000 Zeilen.
Zunächst wird die gesamte Datei in den Speicher kopiert. Dann 4 Arrays vom Typ int (8 Bytes) multipliziert mit der Anzahl der Zeilen. Natürlich wird der Arbeitsspeicher schnell erschöpft sein.
Um mit großen Dateien zu arbeiten, sollte das Lesen und Schreiben sektorweise erfolgen, und dabei wird nicht einmal unnötiger Speicher freigesetzt.78 Mbyte - das sind etwa 1.000.000 Zeilen.
Zunächst wird die gesamte Datei in den Speicher kopiert. Dann 4 Arrays vom Typ int (8 Bytes) multipliziert mit der Anzahl der Zeilen. Natürlich wird der Arbeitsspeicher schnell erschöpft sein.
Um mit großen Dateien zu arbeiten, muss ich Sektor für Sektor lesen und schreiben, aber dabei wird nicht einmal unnötiger Speicher freigegeben.Die Datei enthält 606004 Zeilen.
Kopiert exlle nicht Daten in den Speicher?
Vielleicht müssen wir die Datei auf andere Weise behandeln, da die meiste Zeit damit verbracht wird, Daten aus der Datei zu lesen, und ich verstehe nicht, warum das so ist.
Für die weitere Arbeit benötige ich ein komplettes Array im Speicher, da ich sonst viel mehr Zeit für das Lesen/Schreiben benötige.
Ich habe eine Frage, meine CSV-Datei ist 78 Megabyte groß, ich möchte sie berechnen, da Excel wegen seiner Größe sehr langsam ist, dachte ich daran, MT5 zu verwenden.
Ich habe ein Skript, das nur liest Daten in Arrays für jede Zeile (57 Arrays zum Lesen aus der Datei und 57 für das Schreiben in eine neue Datei), die Größe des Arrays ist gleich der Anzahl der Zeilen in CSV-Datei. Das Skript beanspruchte also 8 GByte Speicher, während Excel weniger als 1,5 GByte benötigte, und der Lese-/Schreibvorgang dauerte in MT5 ganze 9 Minuten!
Sie haben 600 000 Strings, von denen jeder bis zu 57 Zellen enthält, die in ein eindimensionales Array string m_cells[] eingelesen werden; das sind 36 Millionen String-Elemente im Array. Der Stringtyp benötigt, wenn ich mich recht erinnere, selbst für eine leere Zeichenfolge 12 Byte. Das sind allein 400 MB an Dienstinformationen (Adressen, Zeichenfolgenlängen), selbst wenn alle Zellen leer sind. Sehen Sie sich an, was passiert, wenn Sie die Größe dieses Arrays ändern, wenn Sie eine neue Zeile hinzufügen:
m_total_rows++;
ArrayResize(m_cells,m_total_rows*m_total_columns,10000);
- Für jede der 36 Millionen Zeilenzellen muss man ein Stück freien Speicher finden, das lang genug ist, es greifen, den Wert an eine neue Stelle kopieren und die Länge buchstabieren. Die Tatsache, dass 10 Tausend Elemente (oder Bytes, ich erinnere mich nicht) mehr Speicher zugewiesen wird, spielt keine Rolle: Wenn eine weitere Zeile kommt, erhöht sich m_total_rows wieder, m_total_rows*m_total_columns auch, und wieder wird Speicher für das Array durch Kopieren neu zugewiesen. Das ist der Grund, warum das Drehbuch so lange dauert.
Der Speicher wird auch bei 32-Bit-Betriebssystemen in Chunks zugewiesen, die ein Vielfaches von 8 Byte sind. Wir können davon ausgehen, dass m_cells nicht (400 + 78) MB, sondern 1 Gb beträgt. Für jede Kopie benötigen wir so viel Speicherplatz, wie m_cells bereits belegt, eine Verdopplung des Speichers würde also 2 GB Speicher beanspruchen. Anstelle von 78 MB, die die eigentlichen Informationen enthalten.
Alles in allem ist dies eine sehr ineffiziente Art der Speicherung in String-Zellen. Ohne die Aufgabe zu kennen, ist es schwierig, genauere Angaben zu machen.
Versuchen Sie, die Funktionen ArraySize() und ArrayResize() zu eliminieren - Sie kennen die Größe. Um auf Nummer sicher zu gehen, nehmen Sie die 2-fache Menge. Ergebnisse berichten
Ich habe eine Frage, meine CSV-Datei ist 78 Megabyte groß, ich möchte sie berechnen, da Excel wegen seiner Größe sehr langsam ist, dachte ich daran, MT5 zu verwenden.
Ich habe ein Skript, das nur liest Daten in Arrays für jede Zeile (57 Arrays zum Lesen aus der Datei und 57 für das Schreiben in eine neue Datei), die Größe des Arrays ist gleich der Anzahl der Zeilen in CSV-Datei. Das Skript beanspruchte also 8 GByte Speicherplatz, während Excel weniger als 1,5 GByte benötigte, und der Lese-/Schreibvorgang dauerte in MT5 ganze 9 Minuten!
Ich hatte dieses Problem einmal. Ich habe eine Menge Korrekturen vorgenommen. Ich kann mich nicht mehr an die ganze Sache erinnern - es war ein einmaliger Auftrag,
aber versuchen,ArrayResize(arrRead_01,arrSize); 3 Parameter zu setzen
|
Experiment.
Sie haben 600 Tausend Strings mit jeweils bis zu 57 Zellen, die in ein eindimensionales Array string m_cells[] eingelesen werden; das sind 36 Millionen String-Elemente in dem Array. Der Stringtyp benötigt, wenn ich mich recht erinnere, selbst für eine leere Zeichenkette 12 Byte. Das sind allein 400 MB an Dienstinformationen (Adressen, Zeichenfolgenlängen), selbst wenn alle Zellen leer sind. Sehen Sie sich an, was passiert, wenn Sie die Größe dieses Arrays ändern, wenn Sie eine neue Zeile hinzufügen:
m_total_rows++;
ArrayResize(m_cells,m_total_rows*m_total_columns,10000);
- Für jede der 36 Millionen Zeilenzellen muss man ein Stück freien Speicher finden, das lang genug ist, es greifen, den Wert an eine neue Stelle kopieren und die Länge buchstabieren. Die Tatsache, dass 10 Tausend Elemente (oder Bytes, ich erinnere mich nicht) mehr Speicher zugewiesen wird, spielt keine Rolle: Wenn eine weitere Zeile kommt, erhöht sich m_total_rows wieder, m_total_rows*m_total_columns auch, und wieder wird Speicher für das Array durch Kopieren neu zugewiesen. Dies ist der Grund für die Langsamkeit des Skripts.
Vielen Dank für die Code-Analyse.
Es fällt mir schwer, OOP zu verstehen, daher ist es für mich eine Qual, Änderungen daran vorzunehmen. So wie ich es verstanden habe, geht es um die Klasse, die für das Lesen zuständig ist, dort wird die ganze Datei in String-Arrays aufgeteilt, und erst dann, wenn ich will, konvertiere ich diese String-Werte in einen anderen Typ und setze sie in Arrays vom Typ int in mein Skript. Wenn ich es richtig verstehe, dann sollte ich, um den Prozess zu beschleunigen, die gesamte Datei lesen und verstehen, wie viele Zeilen und Spalten es gibt und wie viele Symbole in jeder Zelle sind, und dann sofort die Feldgröße auswählen? Wie können wir es dann tun?
Der Speicher wird auch bei 32-Bit-Betriebssystemen in Chunks zugewiesen, die ein Vielfaches von 8 Byte sind. Wir können davon ausgehen, dass m_cells 1 Gb belegt, nicht (400 + 78) Mb. Für jede Kopie benötigen wir so viel Speicherplatz, wie m_cells bereits belegt, eine Verdopplung des Speichers würde also 2 GB Speicherplatz beanspruchen. Anstelle der 78 MB, die die eigentlichen Informationen enthalten.
Alles in allem eine sehr ineffiziente Art, in String-Zellen zu speichern. Ohne die Aufgabe zu kennen, ist es schwierig, genauere Angaben zu machen.
Ich würde gerne verstehen, woher die 400 Megabyte auf einmal kommen? Habe ich richtig verstanden, dass Speicher zugewiesen wird, aber zuvor zugewiesener Speicher nicht gelöscht/freigegeben wird?
Versuchen Sie, ArraySize() und ArrayResize() herauszuwerfen - Sie kennen die Größe. Nehmen Sie für alle Fälle eine 2-fache Größe... Informieren Sie mich über das Ergebnis
Von wo aus soll aus einem Skript oder einer Klasse gedumpt werden? Die Größe ist bekannt, da ich die Dateigröße kenne? Aber die Datei kann eine andere Größe haben, das Skript ist nicht auf einmal fertig...
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Ich habe eine Frage, meine CSV-Datei ist 78 Megabyte groß, ich möchte sie berechnen, da Excel wegen seiner Größe sehr langsam ist, dachte ich daran, MT5 zu verwenden.
Ich habe ein Skript, das nur liest Daten in Arrays für jede Zeile (57 Arrays zum Lesen aus der Datei und 57 für das Schreiben in eine neue Datei), die Größe des Arrays ist gleich der Anzahl der Zeilen in CSV-Datei. Das Skript beanspruchte also 8 Gigabyte Arbeitsspeicher, während Excel weniger als 1,5 Gigabyte groß ist, und der Lese-/Schreibvorgang dauerte bei MT5 ganze 9 Minuten!