Witam mam utworzone dwa podejścia do tworzenia dużych plików, uruchomić programu na Windows 7, 64-bit, 8 GB RAM maszyny, JDK 8 i poniżej są wyniki.
W obu przypadkach utworzono plik 180 MB zawierający liczbę w każdej linii od 1 do 20 milionów (2 crore w systemie indyjskim).
pamięć programu Java rośnie stopniowo till 600 MB
pierwsze wyjście
Approach = approach-1 (Using FileWriter)
Completed file writing in milli seconds = 4521 milli seconds.
drugie wyjście
Approach = approach-2 (Using FileChannel and ByteBuffer)
Completed file writing in milli seconds = 3590 milli seconds.
Jedno spostrzeżenie - Jestem obliczania pozycji (zmienny pos) podejścia nr 2, jeśli skomentuję, to tylko ostatni ciąg będzie widoczny z powodu nadpisania na pozycji, ale czas zmniejszony do prawie 2000 milli sekund.
Dołączanie kodu.
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.TimeUnit;
public class TestLargeFile {
public static void main(String[] args) {
writeBigFile();
}
private static void writeBigFile() {
System.out.println("--------writeBigFile-----------");
long nanoTime = System.nanoTime();
String fn = "big-file.txt";
boolean approach1 = false;
System.out.println("Approach = " + (approach1 ? "approach-1" : "approach-2"));
int numLines = 20_000_000;
try {
if (approach1) {
//Approach 1 -- for 2 crore lines takes 4.5 seconds with 180 mb file size
approach1(fn, numLines);
} else {
//Approach 2 -- for 2 crore lines takes nearly 2 to 2.5 seconds with 180 mb file size
approach2(fn, numLines);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Completed file writing in milli seconds = " + TimeUnit.MILLISECONDS.convert((System.nanoTime() - nanoTime), TimeUnit.NANOSECONDS));
}
private static void approach2(String fn, int numLines) throws IOException {
StringBuilder sb = new StringBuilder();
FileChannel rwChannel = new RandomAccessFile(fn, "rw").getChannel();
ByteBuffer wrBuf;
int pos = 0;
for (int i = 1; i <= numLines; i++) {
sb.append(i).append(System.lineSeparator());
if (i % 100000 == 0) {
wrBuf = rwChannel.map(FileChannel.MapMode.READ_WRITE, pos, sb.length());
pos += sb.length();
wrBuf.put(sb.toString().getBytes());
sb = new StringBuilder();
}
}
if (sb.length() > 0) {
wrBuf = rwChannel.map(FileChannel.MapMode.READ_WRITE, pos, sb.length());
wrBuf.put(sb.toString().getBytes());
}
rwChannel.close();
}
private static void approach1(String fn, int numLines) throws IOException {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= numLines; i++) {
sb.append(i).append(System.lineSeparator());
}
FileWriter fileWriter = new FileWriter(fn);
fileWriter.write(sb.toString());
fileWriter.flush();
fileWriter.close();
}
}
Usuwanie pliku nie jest konieczne. Nadpisujesz to. –
Ile czasu zajmuje procesor i ile czasu we/wy ("system")? W przypadku dużych plików tworzenie ogromnego ciągu 'textToSave' może zdominować czas. – Raedwald
Nie dotyczy bezpośrednio Twojego pytania: Możesz rozważyć zmianę instrukcji out.close(), aby można było to zrobić w bloku finally. W przypadku wystąpienia błędu przy zapisie, będzie on nadal zamknięty. –