G
Guest
Gast
Ahoi!
Ich versuche gerade so fix wie möglich ein riesiges double-Array auf die HDD zu schreiben und es von dort wieder zu rekonstruieren.
Als Kandidaten fielen mir hierfür ein: DataOutputStream und ObjectOutputStream (bzw. jeweils *Input*).
Folgender Mini-Benchmark zeigt, dass ObjectOutputStream wesentlich schneller ist. Meine Ergebnisse:
Allerdings schafft eine zum Vergleich in PureBasic gecodete und in Maschinencode übersetzte Version für denselben Zweck mit einiges Tricks Laufzeiten von um die 700 (streaming out) und nur 120 (streaming in), also nochmals stark beschleunigt. Auch habe ich bereits die PureBasic-gecodeten Routinen in eine DLL gepackt und dann per JNI von Java aus aufgerufen. Auch diese Variante ist immernoch (wenn auch nur noch geringfügig) schneller.
Hat also noch jemand eine Idee, wie das mit Java-eigenen Mitteln zu beschleunigen geht ? Irgendwie direkt von der Datei in den Speicher streamen, oder so ?
Der Speedcontest ist eröffnet ;-)
Danke + Guten Morgen,
kopfsalat
Hier meine Testklassen:
Die Datenhaltungs-Klasse
Die Datei, um den Benchmark-Test zu starten
Ich versuche gerade so fix wie möglich ein riesiges double-Array auf die HDD zu schreiben und es von dort wieder zu rekonstruieren.
Als Kandidaten fielen mir hierfür ein: DataOutputStream und ObjectOutputStream (bzw. jeweils *Input*).
Folgender Mini-Benchmark zeigt, dass ObjectOutputStream wesentlich schneller ist. Meine Ergebnisse:
Streaming out: 10 x 1000000 doubles
dos-time : 24422
oos-time : 1203
Streaming in: 10 x 1000000 doubles
dis-time : 16344
ois-time : 1063
Allerdings schafft eine zum Vergleich in PureBasic gecodete und in Maschinencode übersetzte Version für denselben Zweck mit einiges Tricks Laufzeiten von um die 700 (streaming out) und nur 120 (streaming in), also nochmals stark beschleunigt. Auch habe ich bereits die PureBasic-gecodeten Routinen in eine DLL gepackt und dann per JNI von Java aus aufgerufen. Auch diese Variante ist immernoch (wenn auch nur noch geringfügig) schneller.
Hat also noch jemand eine Idee, wie das mit Java-eigenen Mitteln zu beschleunigen geht ? Irgendwie direkt von der Datei in den Speicher streamen, oder so ?
Der Speedcontest ist eröffnet ;-)
Danke + Guten Morgen,
kopfsalat
Hier meine Testklassen:
Die Datenhaltungs-Klasse
Code:
package serializableSpeed;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
public class MyData implements Serializable {
private static final long serialVersionUID = -2319633440412883951L;
private double[] data;
public void initializeByRandom(int size) {
data = new double[size];
for (int i=0; i<size; i++) {
data[i] = Math.sin(i * 1.0 / 44100);
}
}
public void saveManuallyDataOutputStream(File file) throws IOException {
FileOutputStream fos = new FileOutputStream(file);
DataOutputStream ds = new DataOutputStream(fos);
ds.writeInt(data.length);
for (int i=0; i<data.length; i++) {
ds.writeDouble(data[i]);
}
ds.flush();
ds.close();
fos.close();
}
public void loadManuallyDataInputStream(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
DataInputStream ds = new DataInputStream(fis);
data = new double[ds.readInt()];
for (int i=0; i<data.length; i++) {
data[i] = ds.readDouble();
}
ds.close();
fis.close();
}
}
Die Datei, um den Benchmark-Test zu starten
Code:
package serializableSpeed;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class RunSpeedTest {
public static void streamTest() throws IOException, ClassNotFoundException {
int size = 1000000;
int count = 10;
MyData dat = new MyData();
dat.initializeByRandom(size);
//
// SAVING
//
System.out.println("Streaming out: " + count + " x " + size + " doubles");
long time = System.currentTimeMillis();
File f;
// saving using a DataOutputStream
for (int i=0; i<count; i++) {
f = new File("dos_" + i + ".dat");
dat.saveManuallyDataOutputStream(f);
}
time = System.currentTimeMillis() - time;
System.out.println("dos-time : " + time); System.out.flush();
// saving using an ObjectOutputStream
time = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
f = new File("oos_" + i + ".dat");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(dat);
oos.flush();
oos.close();
fos.close();
}
time = System.currentTimeMillis() - time;
System.out.println("oos-time : " + time);
System.out.flush();
//
// LOADING
//
System.out.println("Streaming in: " + count + " x " + size + " doubles");
dat.initializeByRandom(0);
// loading using a DataOutputStream
time = System.currentTimeMillis();
for (int i=0; i<count; i++) {
f = new File("dos_" + i + ".dat");
dat.loadManuallyDataInputStream(f);
}
time = System.currentTimeMillis() - time;
System.out.println("dis-time : " + time); System.out.flush();
// loading using an ObjectInputStream
@SuppressWarnings("unused")
MyData du;
time = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
f = new File("oos_" + i + ".dat");
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
du = (MyData) ois.readObject();
ois.close();
fis.close();
}
time = System.currentTimeMillis() - time;
System.out.println("ois-time : " + time);
System.out.flush();
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
streamTest();
System.out.println("\nFINISHED");
}
}