基本上我现在所做的是比较通过反射/我自己的实现来保存/加载所需的时间。
测试代码:
主类(Comparision.class)
package de.cammeritz.chunksaver.util;
import java.io.File;
/**
* Created by Fabian / Cammeritz on 20.10.2017 at 03:15.
*/
public class Comparision {
public static void main(String args[]) {
long start;
long end;
//Preparing datasets
DataSerializable dataSerializable = createSerializable();
DataExternalizable dataExternalizable = createExternalizable();
//Storage files
File sFile = new File(System.getProperty("user.dir"), "sFile.dat");
File eFile = new File(System.getProperty("user.dir"), "eFile.dat");
//Saving via reflection
start = System.currentTimeMillis();
FileUtil.save(dataSerializable, sFile);
end = System.currentTimeMillis();
System.out.println("Time taken to save via reflection in milliseconds: " + (end - start));
//Saving via my own code
start = System.currentTimeMillis();
FileUtil.save(dataExternalizable, eFile);
end = System.currentTimeMillis();
System.out.println("Time taken to save via my own code in milliseconds: " + (end - start));
//Loading via reflection
start = System.currentTimeMillis();
dataSerializable = (DataSerializable) FileUtil.load(sFile);
end = System.currentTimeMillis();
System.out.println("Time taken to load via reflection in milliseconds: " + (end - start));
//Loading via my own code
start = System.currentTimeMillis();
dataExternalizable = (DataExternalizable) FileUtil.load(eFile);
end = System.currentTimeMillis();
System.out.println("Time taken to save via my own code in milliseconds: " + (end - start));
}
private static DataSerializable createSerializable() {
DataSerializable data = new DataSerializable(7);
for (int cx = 0; cx < data.getSideSize(); cx++) {
for (int cz = 0; cz < data.getSideSize(); cz++) {
for (int x = 0; x < data.getX(); x++) {
for (int y = 0; y < data.getY(); y++) {
for (int z = 0; z < data.getZ(); z++) {
data.setValue(cx, cz, x, y, z, (byte) 0x7f);
}
}
}
}
}
return data;
}
private static DataExternalizable createExternalizable() {
DataExternalizable data = new DataExternalizable(7);
for (int cx = 0; cx < data.getSideSize(); cx++) {
for (int cz = 0; cz < data.getSideSize(); cz++) {
for (int x = 0; x < data.getX(); x++) {
for (int y = 0; y < data.getY(); y++) {
for (int z = 0; z < data.getZ(); z++) {
data.setValue(cx, cz, x, y, z, (byte) 0x7f);
}
}
}
}
}
return data;
}
}
通过反射进行序列化:
package de.cammeritz.chunksaver.util;
import java.io.Serializable;
/**
* Created by Fabian / Cammeritz on 20.10.2017 at 02:59.
*/
public class DataSerializable implements Serializable {
private final int x = 16;
private final int y = 256;
private final int z = 16;
private byte[][][][][] ids = null;
private int sideSize;
public DataSerializable(int sideSize) {
this.sideSize = sideSize;
ids = new byte[sideSize][sideSize][16][256][16];
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
public int getSideSize() {
return sideSize;
}
public byte getValue(int cx, int cz, int x, int y, int z) {
return ids[cx][cz][x][y][z];
}
public void setValue(int cx, int cz, int x, int y, int z, byte value) {
ids[cx][cz][x][y][z] = value;
return;
}
}
通过我自己的实现进行序列化:
package de.cammeritz.chunksaver.util;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Created by Fabian / Cammeritz on 20.10.2017 at 02:58.
*/
public class DataExternalizable implements Externalizable {
private final int x = 16;
private final int y = 256;
private final int z = 16;
private byte[][][][][] ids = null;
private int sideSize;
public DataExternalizable() {
}
public DataExternalizable(int sideSize) {
this.sideSize = sideSize;
ids = new byte[sideSize][sideSize][16][256][16];
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
public int getSideSize() {
return sideSize;
}
public byte getValue(int cx, int cz, int x, int y, int z) {
return ids[cx][cz][x][y][z];
}
public void setValue(int cx, int cz, int x, int y, int z, byte value) {
ids[cx][cz][x][y][z] = value;
return;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(ids);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
ids = (byte[][][][][]) in.readObject();
}
}
基本上我可以同意上面@markspace 所说的(“我认为Serializable 很慢的想法相当陈旧。像7 和8 这样的现代JVM 实现了很多加速以帮助Serializable 运行得更快。我会从那个开始如果它实际上运行速度比可接受的慢,则仅进一步调查”)以及@EJP所说的(“我认为@markspace在这里的钱是正确的。你不需要它尽可能快,你需要它足够快。在过去,我们必须以足够快的速度进行排序合并,这样他们就不会遇到第二次操作员轮班。任何比这更快的速度真的没有回报。“)
现在测试的问题是结果非常混乱,也表明我肯定会在这里使用 Externalizable。
3 次测试的结果具有相同的值和确切大小的数据集,我稍后将在我的项目中需要:
Time taken to save via reflection in milliseconds: 746
Time taken to save via my own code in milliseconds: 812
Time taken to load via reflection in milliseconds: 3191
Time taken to save via my own code in milliseconds: 2811
Time taken to save via reflection in milliseconds: 755
Time taken to save via my own code in milliseconds: 934
Time taken to load via reflection in milliseconds: 3545
Time taken to save via my own code in milliseconds: 2671
Time taken to save via reflection in milliseconds: 401
Time taken to save via my own code in milliseconds: 784
Time taken to load via reflection in milliseconds: 3065
Time taken to save via my own code in milliseconds: 2627
对此我感到困惑的是,反射实现的保存速度比我自己的实现快得多,但相反,加载数据需要大约 1 秒的时间。
现在的重点是,这 1 秒对于我计划做的事情非常重要,因为保存并不重要,但加载必须快速完成。所以结果清楚地告诉我,我应该在这里使用 Externalizable 方式。
但是这里的任何人都可以告诉我为什么反射方式保存得更快,以及我如何改进我自己的保存数据的实现?
谢谢大家!