Cómo acelerar / optimizar la escritura de archivos en mi programa

Okay. Se supone que debo escribir un programa para tomar un archivo de 20 GB como entrada con 1,000,000,000 de registros y crear algún tipo de índice para un acceso más rápido. Básicamente, he decidido dividir los registros de 1 bil en 10 cubos y 10 subgrupos dentro de ellos. Estoy calculando dos valores hash para que el registro ubique su depósito apropiado. Ahora, creo 10 * 10 archivos, uno para cada subgrupo. Y cuando extraigo el registro del archivo de entrada, decido a cuál de los 100 archivos va; luego agregue el desplazamiento del registro a ese archivo en particular. He probado esto con un archivo de muestra con 10,000 registros. He repetido el proceso 10 veces. Emulando efectivamente un archivo de 100,000 registros. Para esto me lleva alrededor de 18 segundos. Esto significa que me llevará una eternidad hacer lo mismo para un archivo de registro de 1 bil. ¿Hay alguna forma de acelerar / optimizar mi escritura?

import java.io.*;

// PROGRAM DOES THE FOLLOWING

// 1. READS RECORDS FROM A FILE. 
// 2. CALCULATES TWO SETS OF HASH VALUES N, M
// 3. APPENDING THE OFFSET OF THAT RECORD IN THE ORIGINAL FILE TO ANOTHER FILE "NM.TXT"  i.e REPLACE THE VALUES OF N AND M.
// 4.  

class storage
{

        public static int siz=10;
    public static FileWriter[][] f;
}

class proxy
{

    static String[][] virtual_buffer;
    public static void main(String[] args) throws Exception
    {
        virtual_buffer = new String[storage.siz][storage.siz]; // TEMPORARY STRING BUFFER TO REDUCE WRITES


        String s,tes;


        for(int y=0;y<storage.siz;y++)
            {
            for(int z=0;z<storage.siz;z++)
            {
            virtual_buffer[y][z]="";            // INITIALISING ALL ELEMENTS TO ZERO
            }
            }




        int offset_in_file = 0;          

        long start = System.currentTimeMillis();


              // READING FROM THE SAME IP FILE 20 TIMES TO EMULATE A SINGLE BIGGER FILE OF SIZE 20*IP FILE
        for(int h=0;h<20;h++){                

         BufferedReader in = new BufferedReader(new FileReader("outTest.txt"));
         while((s = in.readLine() )!= null)
         {
            tes = (s.split(";"))[0];
            int n = calcHash(tes); // FINDING FIRST HASH VALUE
            int m = calcHash2(tes); // SECOND HASH
            index_up(n,m,offset_in_file); // METHOD TO WRITE TO THE APPROPRIATE FILE I.E NM.TXT
                offset_in_file++;

         }
         in.close();
        }



         System.out.println(offset_in_file);
         long end = System.currentTimeMillis();
         System.out.println((end-start));
    }




    static int calcHash(String s) throws Exception

    {
        char[] charr = s.toCharArray();;
        int i,tot=0;
        for(i=0;i<charr.length;i++)
        {
            if(i%2==0)tot+= (int)charr[i];
        }
        tot = tot % storage.siz;
        return tot;
    }




       static int calcHash2(String s) throws Exception

    {
        char[] charr = s.toCharArray();
        int i,tot=1;
        for(i=0;i<charr.length;i++)
        {
            if(i%2==1)tot+= (int)charr[i];
        }   
        tot = tot % storage.siz;
        if (tot<0)
            tot=tot*-1;
        return tot;
    }


      static void index_up(int a,int b,int off) throws Exception
   {
    virtual_buffer[a][b]+=Integer.toString(off)+"'"; // THIS BUFFER STORES THE DATA TO BE WRITTEN
    if(virtual_buffer[a][b].length()>2000)           // TO A FILE BEFORE WRITING TO IT, TO REDUCE NO. OF WRITES
    {                                                .

    String file = "c:\\adsproj\\"+a+b+".txt";   
    new writethreader(file,virtual_buffer[a][b]);    // DOING THE ACTUAL WRITE PART IN A THREAD.
    virtual_buffer[a][b]="";


    }
    }
}



class writethreader implements Runnable
{
    Thread t;
    String name, data;
    writethreader(String name, String data)
    {
        this.name = name;
        this.data = data;

        t = new Thread(this);
        t.start();
    }

    public void run()
    {
        try{


        File f = new File(name);
        if(!f.exists())f.createNewFile();   
        FileWriter fstream = new FileWriter(name,true);  //APPEND MODE 
        fstream.write(data);
        fstream.flush(); fstream.close();
            }
        catch(Exception e){}
    }
}
Respuesta 1

Considere usar VisualVM para identificar los cuellos de botella. Todo lo demás a continuación se basa en conjeturas, y las conjeturas de rendimiento a menudo son muy, muy malas.

Yo creo que tiene dos problemas con su estrategia de escritura.

La primera es que está comenzando un nuevo hilo en cada escritura; el segundo es que estás volviendo a abrir el archivo en cada escritura.

El problema del hilo es especialmente malo, creo, porque no veo nada que impida que un hilo escrito en un archivo se superponga con otro. ¿Qué pasa entonces? Francamente, no lo sé, pero dudo que sea bueno.

Considere, en cambio, crear una matriz de archivos abiertos para los 100. Su sistema operativo puede tener un problema con esto, pero creo que probablemente no. Luego cree una cola de trabajo para cada archivo. Cree un conjunto de subprocesos de trabajo (100 es demasiados, piense en 10 más o menos) donde cada uno "posee" un conjunto de archivos que recorre, generando y vaciando la cola para cada archivo. Preste atención a la interacción entre hilos entre el lector y el escritor de colas: use una clase de cola adecuada.

Respuesta: 2

¿Existe una herramienta para crear la clase DBManager para bases de datos simples en SQL? Quiero usarlo junto con netbeans. Estoy trabajando en un proyecto simple de minería de datos de tareas. Pero estoy harto de escribir ...

Tengo un servicio web que expone un mbean. Puedo ver ese mbean usando jconsole. Ahora necesito esa función expuesta en un nuevo sitio web de tomcat.

Tengo una tarea de mi universidad para continuar un proyecto de tarjeta JAVA de los estudiantes del último semestre, que resulta ser una mierda. Porque tenemos que seguir trabajando con alguien en lugar del nuestro ...

En primer lugar, cuando digo flujo de caracteres de mezcla de protocolo http con flujo de bytes, quiero decir que el encabezado de solicitud es flujo de caracteres y el cuerpo de solicitud es flujo de bytes (especificado por la longitud del contenido), están separados por un ...