2012-09-21 12 views
5

Mam problemy z wydajnością Java IO.Java IO Performance XOR z 2 plikami

Przede wszystkim przeczytałem tutaj moje wskazówki dotyczące wydajności, którą starałem się wdrożyć.

Ale tu jest mój problem:

Z małych plików (do 400MB), to dość szybko. Ale prawdziwe pliki, z którymi będę pracował, mają około 30 GB. A dzięki nim spowalniają jak diabli.

Co robi: Weź 2 pliki, wykonaj wyłączne lub i napisz nowy plik.

BTW: Nie martw się cięciem pliku na końcu. Chodzi o naprawienie małego błędu, którego jeszcze nie znalazłem.

Mam nadzieję, że ktoś ma dla mnie wskazówkę. Dzięki.

Pozdrowienia Timo

import java.io.File; 
import java.io.IOException; 
import java.io.RandomAccessFile; 
import java.nio.ByteBuffer; 
import java.nio.channels.FileChannel; 

public class main { 
    public static void main(String[] args) throws IOException { 

     final long start = System.currentTimeMillis(); 
     // Init. FileChannel1 
     final File file1 = new File("/home/tmann/Downloads/test/1.zip"); 
     final RandomAccessFile fis1 = new RandomAccessFile(file1, "rw"); 
     final FileChannel ch1 = fis1.getChannel(); 

     // Init. FileChannel2 
     final File file2 = new File("/home/tmann/Downloads/test/2.zip"); 
     final RandomAccessFile fis2 = new RandomAccessFile(file2, "rw"); 
     final FileChannel ch2 = fis2.getChannel(); 
     // Init FileChannel3 
     final File file3 = new File("/home/tmann/Downloads/test/32.zip"); 
     final RandomAccessFile fis3 = new RandomAccessFile(file3, "rw"); 
     final FileChannel ch3 = fis3.getChannel(); 
     // Init ByteBuffer1 

     final ByteBuffer bytebuffer1 = ByteBuffer.allocate(65536); 
     // Init ByteBuffer2 
     final ByteBuffer bytebuffer2 = ByteBuffer.allocate(65536); 
     // Init ByteBuffer3 
     final ByteBuffer bytebuffer3 = ByteBuffer.allocate(65536); 


     int byte1 = 0; 
     int byte2 = 0; 

     final byte[] array1 = bytebuffer1.array(); 
     final byte[] array2 = bytebuffer2.array(); 
     final byte[] array3 = bytebuffer3.array(); 

     int count = 0; 

     while (byte1 != -1) { 
      byte1=ch1.read(bytebuffer1); 
      byte2=ch2.read(bytebuffer2); 
       while (count < byte1) { 
         array3[count] = (byte) (array1[count]^array2[count]); 
         count++; 
             } 

      bytebuffer3.put(array3); 

      bytebuffer1.flip(); 
      bytebuffer2.flip(); 
      bytebuffer3.flip(); 

       while (bytebuffer3.hasRemaining()) { 
         ch3.write(bytebuffer3); 
                } 

      bytebuffer1.clear(); 
      bytebuffer2.clear(); 
      bytebuffer3.clear(); 

     } 

     fis3.setLength(fis3.length()-59858); 
     final long endvar = System.currentTimeMillis(); 
     System.out.println((500.0/((endvar - start)/1000f)) + "MB/s"); 

    } 
} 
+3

Jeśli masz 64-bitową maszynę JVM, używałbym plików mapowanych w pamięci. Będę też XOR dłubał zamiast jednego bajtu na raz, jeśli możesz (to może być do 8x szybciej) –

+1

XOR longs przyniósł miłą prędkość, dzięki. :) – user1688035

Odpowiedz

2

Dlaczego trzeba RandomAccessFile ją czytać po kolei?

Czy próbowałeś użyć prostego BufferedInputStream przez FileInputStream?

+1

+1 Podejrzewam, że używa On RandomAccessFile, ponieważ jest używany do czytania i pisania. Zamiast tego można użyć FileInputStream i FileOutputStream. –

+0

Zaimplementuję plik "w pliku" lub wyślemy go do edycji. Próbowałem również ... jeszcze wolniej .. :( – user1688035