MT5 RAM-Speicherüberfluss, Probleme beim Lesen/Schreiben großer Dateien - Seite 6

 
Vladimir:

Ich empfehle, zunächst eine minimale Änderung vorzunehmen, damit die Neuzuweisung von Speicher weniger häufig erfolgt. Zwei Zeilen

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

in bool CSVReader::AddData(string data_str,bool header) ersetzen durch

m_total_rows++;
if (m_total_rows*m_total_columns>ArraySize(m_cells)) ArrayResize(m_cells,2*m_total_rows*m_total_columns);

Die Anzahl der Speicherneuzuweisungen mit Kopieren sollte O(log(n,2)) statt O(n) werden. 20 anstelle von 600 Tausend. Vielleicht ist das jetzt genug für Sie.

Ich danke Ihnen! Ich möchte Sie wissen lassen, was ich habe:

1. Keine Veränderung des Speichers - um 10 Gigabyte hat der aktuelle Code hier und da RAM gefressen.

2. Nach Geschwindigkeit:

2.1 Alte Version 574 Sekunden

2018.07.22 02:08:18.694 Scripts script Pred_Ocenka (Si Splice,M1) loaded successfully
2018.07.22 02:17:52.059 Scripts script Pred_Ocenka (Si Splice,M1) removed

2.2 Neue Version: 138 Sekunden.

2018.07.22 02:22:16.728 Scripts script Pred_Ocenka (Si Splice,M1) loaded successfully
2018.07.22 02:24:34.569 Scripts script Pred_Ocenka (Si Splice,M1) removed

Sie erhalten also einen 4-fachen Gewinn, was ziemlich gut ist! Allerdings ist der Speicherplatz knapp, und das ist bei weitem nicht alles, was geladen werden muss....

 
Maxim Dmitrievsky:

sehr praktisch :)

Also habe ich CSV in Binärdateien umgewandelt, ohne das Datum.

Wie sich herausstellte, beanspruchte das Skript bei der Ausführung 1 Gigabyte Speicherplatz, was im Vergleich zu 10 Gigabyte sehr gut ist. Aber immer noch eine Menge :)

Was die Geschwindigkeit betrifft - nur 16 Sekunden! Ziemlich gut!

2018.07.22 02:35:12.338 Scripts script Pred_Ocenka_02 (Si Splice,M1) loaded successfully
2018.07.22 02:35:28.334 Scripts script Pred_Ocenka_02 (Si Splice,M1) removed
 
Vladimir:

Ich empfehle, zunächst eine minimale Änderung vorzunehmen, damit die Neuzuweisung von Speicher weniger häufig erfolgt. Zwei Zeilen

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

in bool CSVReader::AddData(string data_str,bool header) ersetzen durch

m_total_rows++;
if (m_total_rows*m_total_columns>ArraySize(m_cells)) ArrayResize(m_cells,2*m_total_rows*m_total_columns);

Die Anzahl der Speicher-Neuzuweisungen mit Kopieren sollte O(log(n,2)) statt O(n) werden. 20 anstelle von 600 Tausend. Vielleicht reicht das für Sie aus.

Eigentlich ist der dritte Parameter für ArrayResize() aus einem bestimmten Grund angegeben... Das ist eine schlechte Veränderung.

Lesen Sie die Dokumentation

 
Roffild:

Eigentlich ist der dritte Parameter für ArrayResize() aus einem bestimmten Grund angegeben... eine federleichte Veränderung...

Lesen Sie die Dokumentation

Was haben Sie aus der Dokumentation über den dritten Parameter herauslesen können, der in diesem Fall nützlich ist, wenn es darum geht, eine .csv-Datei in den Speicher zu heben, die in verschiedenen Programmen erstellt wurde und eine beliebige Größe hat?

Fühlen Sie sich frei, eine bessere, nicht-binäre Änderung vorzuschlagen, die die Geschwindigkeit der Speicher-Neuzuweisung (Reduzierung der Anzahl der ArrayResize-Aufrufe) mehr als die binäre Suche erhöht...

 
Aleksey Vyazmikin:

Ich danke Ihnen! Ich werde Sie wissen lassen, was dabei herauskommt:

1. Keine Veränderung des Arbeitsspeichers - um 10 Gigabyte hat der aktuelle Code hier und da RAM gefressen.

2. Nach Geschwindigkeit:

2.1 Alte Version 574 Sekunden

2.2 Neue Version: 138 Sekunden.

Sie erhalten also einen 4-fachen Gewinn, was ziemlich gut ist! Allerdings ist der Speicherplatz knapp, und es ist nicht allzu viel zu laden....

Nach dem Lesen, in bool CSVReader::Load(int start_line), nach der Zeile

FileClose(filehandle);

Speicherfreigabe einfügen

ArrayResize(m_cells,m_total_rows*m_total_columns);

Gibt unnötige 0-50% des von m_cells belegten Speichers frei. Nur m_cells selbst, ohne Zellinhalte.

 

Jetzt mache ich eine kleine Bibliothek für schnelle CSV-Verarbeitung.

Auf dem Screenshot ist ein Testlauf zu sehen, der in 7 Sekunden abgeschlossen ist!!! Xeon-Prozessor, Frequenz 3.0.

Zunächst erstellt das Skript das Datenformat für jede Spalte. Es gibt 6 Spalten. Dann werden der Tabelle 1000000 Zeilen hinzugefügt, die dann mit Zahlen von 0 bis 999999 gefüllt werden. Je nach Datenformat können die Zahlen unterschiedlich wahrgenommen werden. Dann wird alles in einer Datei gespeichert.

Die Datei ist 65,4 MB groß. Die gesamte Struktur beanspruchte 232 MB im Speicher.

 
Aleksey Vyazmikin:

Also habe ich CSV in Binärdateien umgewandelt, ohne das Datum.

Wie sich herausstellte, beanspruchte das Skript bei der Ausführung 1 Gigabyte Speicherplatz, was im Vergleich zu 10 Gigabyte sehr gut ist. Aber immer noch eine Menge :)

Was die Geschwindigkeit betrifft - nur 16 Sekunden! Ziemlich gut!

Nun, das Skript selbst ist immer noch verkrüppelt.

 
Vladimir:

Nach dem Lesen, in bool CSVReader::Load(int start_line), nach Zeile

FileClose(filehandle);

Speicherfreigabe einfügen

ArrayResize(m_cells,m_total_rows*m_total_columns);

Gibt die unnötigen 0-50% des von m_cells belegten Speichers frei. Nur m_cells selbst, ohne Zellinhalte.

Danke, aber nach dem Schließen der Datei/der Beendigung des Skripts wird der Speicher ohnehin schnell wieder freigegeben. So können Sie den Verbrauch beim Laufen reduzieren....

 
Aliaksandr Hryshyn:

Jetzt mache ich eine kleine Bibliothek für schnelle CSV-Verarbeitung.

Auf dem Screenshot ist ein Testlauf zu sehen, der in 7 Sekunden abgeschlossen ist!!! Xeon-Prozessor, Frequenz 3.0.

Zunächst erstellt das Skript das Datenformat für jede Spalte. Es gibt 6 Spalten. Dann werden der Tabelle 1000000 Zeilen hinzugefügt, die dann mit Zahlen von 0 bis 999999 gefüllt werden. Je nach Datenformat können die Zahlen unterschiedlich wahrgenommen werden. Dann wird alles in einer Datei gespeichert.

Die Datei ist 65,4 MB groß. Die gesamte Struktur beanspruchte 232 MB im Speicher.

Ziemlich interessant. Planen Sie, Ihre Programmierleistungen öffentlich zu veröffentlichen?

 
Maxim Dmitrievsky:

Nun, das Drehbuch selbst ist immer noch ein Chaos.

Können Sie mir sagen, was ich daran ändern kann?

#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 ArrTest[][57];

CsvWriter Printer;
int Statistic;

int StrokTotal=0;
int arrSize=0;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int arrTest2[][57];
   int r=FileOpen("PredFind\\Test\\test.bin",FILE_BIN|FILE_READ);
   if(r!=INVALID_HANDLE) 
     { 
      FileReadArray(r,arrTest2,0,WHOLE_ARRAY);
      Print(arrTest2[1][1]);
      arrSize=ArraySize(arrTest2)/57;
      StrokTotal=arrSize;
      Print(arrSize);

     ArrayFree(ArrTest); 
     ArrayResize(ArrTest,arrSize);

      for(int i=1;i<StrokTotal; i++)
        {
         for(int s=1;s<56+1; s++)
           {   
            //Print("s=",s);
            ArrTest[i,s]=arrTest2[i,s];
           }
        }
         Print(ArrTest[2,1]);
      for(int i=1;i<StrokTotal; i++)
        {
         for(int s=3;s<56+1; s++)
           {               
            if (ArrTest[i,s]>=0)ArrTest[i,s]=ArrTest[i,s]*ArrTest[i,1];
            else ArrTest[i,s]=ArrTest[i,s]*ArrTest[i,2];
           }
        }
   }
     else Print("File open failed, error ",GetLastError()); 
/*    
   int h=FileOpen("PredFind\\Test\\test.bin",FILE_BIN|FILE_WRITE);
   FileWriteArray(h,ArrTest,0,WHOLE_ARRAY);
   FileClose(h);
*/
   
    
   string TimeF=TimeToString(TimeLocal(),TIME_DATE|TIME_MINUTES);
   StringSetCharacter(TimeF,13,'_');
   Statistic=Printer.FileCreate(Symbol()+"_"+TimeF+"_""Pred_Ocenka_Write","PredFind\\Test",false,false,EvryTick); //Создание файла для записи     
   Printer.Write(
                 "arr_Data",
                 "arr_Buy_Sell",
                 "arr_Buy_Sell"
                 );

   for(int i=1;i<arrSize; i++)
     {
      Printer.Write(
                    IntegerToString(0),
                    IntegerToString(ArrTest[i,1]),
                    IntegerToString(ArrTest[i,2]),
                    IntegerToString(ArrTest[i,3]),
                    IntegerToString(ArrTest[i,4]),
                    IntegerToString(ArrTest[i,5]),
                    IntegerToString(ArrTest[i,6]),
                    IntegerToString(ArrTest[i,7]),
                    IntegerToString(ArrTest[i,8]),
                    IntegerToString(ArrTest[i,9]),
                    IntegerToString(ArrTest[i,10]),
                    IntegerToString(ArrTest[i,11]),
                    IntegerToString(ArrTest[i,12]),
                    IntegerToString(ArrTest[i,13]),
                    IntegerToString(ArrTest[i,14]),
                    IntegerToString(ArrTest[i,15]),
                    IntegerToString(ArrTest[i,16]),
                    IntegerToString(ArrTest[i,17]),
                    IntegerToString(ArrTest[i,18]),
                    IntegerToString(ArrTest[i,19]),
                    IntegerToString(ArrTest[i,20]),
                    IntegerToString(ArrTest[i,21]),
                    IntegerToString(ArrTest[i,22]),
                    IntegerToString(ArrTest[i,23]),
                    IntegerToString(ArrTest[i,24]),
                    IntegerToString(ArrTest[i,25]),
                    IntegerToString(ArrTest[i,26]),
                    IntegerToString(ArrTest[i,27]),
                    IntegerToString(ArrTest[i,28]),
                    IntegerToString(ArrTest[i,29]),
                    IntegerToString(ArrTest[i,30]),                                                                                
                    IntegerToString(ArrTest[i,31]),
                    IntegerToString(ArrTest[i,32]),
                    IntegerToString(ArrTest[i,33]),
                    IntegerToString(ArrTest[i,34]),
                    IntegerToString(ArrTest[i,35]),
                    IntegerToString(ArrTest[i,36]),
                    IntegerToString(ArrTest[i,37]),
                    IntegerToString(ArrTest[i,38]),
                    IntegerToString(ArrTest[i,39]),
                    IntegerToString(ArrTest[i,40]),
                    IntegerToString(ArrTest[i,41]),
                    IntegerToString(ArrTest[i,42]),
                    IntegerToString(ArrTest[i,43]),
                    IntegerToString(ArrTest[i,44]),
                    IntegerToString(ArrTest[i,45]),
                    IntegerToString(ArrTest[i,46]),
                    IntegerToString(ArrTest[i,47])
                    );
     }
  }