Voracidad de la memoria RAM de la MT5, problemas con la lectura/escritura de archivos grandes - página 6

 
Vladimir:

Recomiendo hacer un cambio mínimo primero, para que la reasignación de memoria se haga con menos frecuencia. Dos líneas

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

en bool CSVReader::AddData(string data_str,bool header) sustituir por

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

El número de reasignaciones de memoria con copia debería ser O(log(n,2)) en lugar de O(n). 20 en lugar de 600 mil. Tal vez eso sea suficiente para ti ahora.

Gracias. Quiero que sepas lo que tengo:

1. No hay cambios en la memoria - por 10 gigabytes el código actual se comió la RAM allí y allá.

2. Por velocidad:

2.1 Versión antigua 574 segundos

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 Nueva versión: 138 segundos.

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

Así que se obtiene una ganancia de 4 veces, ¡lo cual es bastante bueno! Sin embargo, la memoria es escasa, y esto no es ni mucho menos todo lo que hay que cargar....

 
Maxim Dmitrievsky:

muy útil :)

Así que convertí el CSV a binario, menos la fecha.

Lo que resulta, cuando se ejecuta el script ocupó 1 gigabyte de memoria, que en comparación con 10 es muy bueno. Sin embargo, sigue siendo mucho :)

En términos de velocidad: ¡sólo 16 segundos! Bastante bien.

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:

Recomiendo hacer un cambio mínimo primero, para que la reasignación de memoria se haga con menos frecuencia. Dos líneas

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

en bool CSVReader::AddData(string data_str,bool header) sustituir por

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

El número de reasignaciones de memoria con copia debería ser O(log(n,2)) en lugar de O(n). 20 en lugar de 600 mil. Tal vez eso sea suficiente para ti.

En realidad, el tercer parámetro de ArrayResize() se especifica por una razón... Es un mal cambio.

Lea la documentación

 
Roffild:

En realidad, el tercer parámetro de ArrayResize() se especifica por una razón... un cambio de pluma...

Lea la documentación

¿Qué has conseguido sacar de la documentación sobre el tercer parámetro, útil para este caso, a la hora de resolver la tarea de levantar en memoria .csv creados en diferentes programas y que tienen un tamaño arbitrario?

Siéntase libre de sugerir un cambio mejor, no binario, que aumente la velocidad de reasignación de memoria (reduciendo el número de llamadas a ArrayResize) más que la búsqueda binaria...

 
Aleksey Vyazmikin:

Gracias. Ya os contaré lo que salga:

1. No hay cambios en la memoria - por 10 gigabytes el código actual se comió la RAM allí y allá.

2. Por velocidad:

2.1 Versión antigua 574 segundos

2.2 Nueva versión: 138 segundos.

Así que se obtiene una ganancia de 4 veces, ¡lo cual es bastante bueno! Sin embargo, la memoria es escasa, y no hay que cargar mucho ....

Después de la lectura, en bool CSVReader::Load(int start_line), después de la línea

FileClose(filehandle);

insertar liberación de memoria

ArrayResize(m_cells,m_total_rows*m_total_columns);

Libera el 0-50% innecesario de la memoria ocupada por m_cells. Sólo m_cells en sí, sin el contenido de las celdas.

 

Ahora estoy haciendo una pequeña biblioteca para trabajar rápidamente con CSV.

¡¡¡En la captura de pantalla hay una prueba que pasa en 7 segundos!!! Procesador Xeon, frecuencia 3.0.

En primer lugar, el script crea el formato de datos para cada columna. Hay 6 columnas. A continuación, se añaden 1000000 filas a la tabla y se rellenan con números del 0 al 999999. Según el formato de los datos, las cifras pueden percibirse de forma diferente. A continuación, todo se guarda en un archivo.

El tamaño del archivo es de 65,4 MB. Toda la estructura ocupaba 232 MB de memoria.

 
Aleksey Vyazmikin:

Así que convertí el CSV a binario, menos la fecha.

Lo que resulta, cuando se ejecuta el script ocupó 1 gigabyte de memoria, que en comparación con 10 es muy bueno. Sin embargo, sigue siendo mucho :)

En términos de velocidad: ¡sólo 16 segundos! Bastante bien.

Bueno, el guión en sí mismo sigue siendo un poco cojo.

 
Vladimir:

Después de la lectura, en bool CSVReader::Load(int start_line), después de la línea

FileClose(filehandle);

insertar liberación de memoria

ArrayResize(m_cells,m_total_rows*m_total_columns);

Libera el 0-50% innecesario de la memoria ocupada por m_cells. Sólo m_cells en sí, sin el contenido de las celdas.

Gracias, pero después de cerrar el archivo/terminar el script, la memoria se libera rápidamente de todos modos. Así se reduce el consumo mientras se corre....

 
Aliaksandr Hryshyn:

Ahora estoy haciendo una pequeña biblioteca para el manejo rápido de CSV.

¡¡¡En la captura de pantalla hay una prueba que pasa en 7 segundos!!! Procesador Xeon, frecuencia 3.0.

En primer lugar, el script crea el formato de datos para cada columna. Hay 6 columnas. A continuación, se añaden 1000000 filas a la tabla y se rellenan con números del 0 al 999999. Según el formato de los datos, las cifras pueden percibirse de forma diferente. A continuación, todo se guarda en un archivo.

El tamaño del archivo es de 65,4 MB. Toda la estructura ocupaba 232 MB de memoria.

Bastante interesante. ¿Piensa publicar sus logros en materia de programación?

 
Maxim Dmitrievsky:

Bueno, el guión en sí sigue siendo un desastre.

¿Puede decirme qué hay que arreglar en él?

#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])
                    );
     }
  }
Razón de la queja: