2012-01-10 11 views
5

Sto leggendo un file che contiene 500000 righe. sto testando per vedere la velocità del filo come multipla il processo ....Leggere un singolo file con thread multipli: dovrebbe accelerare?

private void multiThreadRead(int num){ 

    for(int i=1; i<= num; i++) { 
     new Thread(readIndivColumn(i),""+i).start(); 
    } 
} 

private Runnable readIndivColumn(final int colNum){ 
    return new Runnable(){ 
     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      try { 

       long startTime = System.currentTimeMillis(); 
       System.out.println("From Thread no:"+colNum+" Start time:"+startTime); 

       RandomAccessFile raf = new RandomAccessFile("./src/test/test1.csv","r"); 
       String line = ""; 
       //System.out.println("From Thread no:"+colNum); 

       while((line = raf.readLine()) != null){ 
        //System.out.println(line); 
        //System.out.println(StatUtils.getCellValue(line, colNum)); 
       } 


       long elapsedTime = System.currentTimeMillis() - startTime; 

       String formattedTime = String.format("%d min, %d sec", 
         TimeUnit.MILLISECONDS.toMinutes(elapsedTime), 
         TimeUnit.MILLISECONDS.toSeconds(elapsedTime) - 
         TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsedTime)) 
        ); 

       System.out.println("From Thread no:"+colNum+" Finished Time:"+formattedTime); 
      } 
      catch (Exception e) { 
       // TODO Auto-generated catch block 
       System.out.println("From Thread no:"+colNum +"===>"+e.getMessage()); 

       e.printStackTrace(); 
      } 
     } 
    }; 
} 

private void sequentialRead(int num){ 
    try{ 
     long startTime = System.currentTimeMillis(); 
     System.out.println("Start time:"+startTime); 

     for(int i =0; i < num; i++){ 
      RandomAccessFile raf = new RandomAccessFile("./src/test/test1.csv","r"); 
      String line = ""; 

      while((line = raf.readLine()) != null){ 
       //System.out.println(line); 
      }    
     } 

     long elapsedTime = System.currentTimeMillis() - startTime; 

     String formattedTime = String.format("%d min, %d sec", 
       TimeUnit.MILLISECONDS.toMinutes(elapsedTime), 
       TimeUnit.MILLISECONDS.toSeconds(elapsedTime) - 
       TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsedTime)) 
      ); 

     System.out.println("Finished Time:"+formattedTime); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
     // TODO: handle exception 
    } 

} 
    public TesterClass() { 

    sequentialRead(1);  
    this.multiThreadRead(1); 

} 

per num = 1 ottengo risultato seguente:

Ora di inizio: 1326224619049

Tempo finale: 2 min, 14 sec

lettura sequenziale FINISCE ...........

multi-thread inizia leggere:

Da Discussione no: 1 Ora di inizio: 1326224753606

Da Discussione no: 1 Tempo finale: 2 min, 13 sec

Multi-Thread leggere ENDS .....

per num = 5 Ottengo il seguente risultato:

formatted Time:10 min, 20 sec 

Sequential read ENDS........... 

Multi-Thread read starts: 

From Thread no:1 Start time:1326223509574 
From Thread no:3 Start time:1326223509574 
From Thread no:4 Start time:1326223509574 
From Thread no:5 Start time:1326223509574 
From Thread no:2 Start time:1326223509574 
From Thread no:4 formatted Time:5 min, 54 sec 
From Thread no:2 formatted Time:6 min, 0 sec 
From Thread no:3 formatted Time:6 min, 7 sec 
From Thread no:5 formatted Time:6 min, 23 sec 
From Thread no:1 formatted Time:6 min, 23 sec 
Multi-Thread read ENDS..... 

La mia domanda è: non dovrebbe leggere la lettura multi-threading. 2,13 sec? Puoi spiegare perché ci vuole troppo tempo con la soluzione multi-thread?

Grazie in anticipo.

+0

possibile duplicato di [applicazione multi-thread Java che legge un singolo file] (http://stackoverflow.com/questions/8126277/java-multi-thread-application-that-reads-a-single-file) –

+0

Il threading non funzionerà a meno che non scriva su un disco diverso, in quel caso entrambi i thread stanno contendendo di scrivere sullo stesso file. Quindi, il threading non funzionerà in quello scenario. –

+0

@TomaszNurkiewicz - Non è la stessa cosa, quello stava usando un thread per file. –

risposta

7

Dal lettura del file è principalmente attesa per il disco I/O, si ha il problema che il disco non girerà più velocemente solo perché è utilizzato da molte discussioni :)

+1

Anche i thread/locking hanno un ruolo in esso? – Bhushan

+0

Probabilmente, la strategia di blocco I/O dipenderà sia dall'implementazione java sia dal sistema operativo sottostante. –

+0

Sto eseguendo un test per lo stesso caso d'uso: la lettura di un singolo file da più thread. Ho scoperto che avere più thread migliora le prestazioni se lo storage sottostante è un'unità disco SATA mentre migliora le prestazioni se è un'unità SAS. Sarebbe a causa della tecnologia point-to-point o il mio test sta facendo qualcosa di sbagliato? –

1

lettura da un file è un processo intrinsecamente seriale , supponendo che non ci sia memorizzazione nella cache, il che significa che esiste un limite alla velocità di recupero dei dati da un file. Anche senza blocchi di file (cioè aprendo il file di sola lettura) tutti i thread dopo il 1 ° si limiteranno a bloccare il disco letto in modo da rendere tutti gli altri thread in attesa e qualunque sia attivo quando i dati diventano disponibili è quello che elabora il file prossimo blocco.

5

Il motivo per cui si sta osservando un rallentamento durante la lettura in parallelo è perché la testina del disco magnetico deve cercare la successiva posizione di lettura (circa 5ms) per ogni thread. Pertanto, la lettura con più thread rimbalza efficacemente il disco tra i tentativi, rallentandolo. L'unico modo consigliato per leggere un file da un singolo disco è leggere in modo sequenziale con un thread.

+0

Grazie per i vostri commenti. Anche se la lettura multi-thread richiede più tempo (es.6,2 minuti invece di 2,10 minuti), ancora posso risparmiare 4/5 minuti mentre sto iterando 5 volte con lettura sequenziale (cioè lettura sequenziale = 10,20 minuti; dove 5 thread = 6,20 minuti) – Hasan

Problemi correlati