可扩展数据集的可序列化或可扩展性,哪个更快更实用?
好的,在我回到我的问题之前,我想先指出我知道Serializable和Exernalizable之间的区别,所以你不需要给出解释!可扩展数据集的可序列化或可扩展性,哪个更快更实用?
我基本上试图做的是将一个类的所有数据保存在一个文件中。 我们已经到了Java 9出来的时候,JVM速度非常快,但仍然有人(我认为他们的观点)认为使用Serializable处理大量数据的效率与使用Exernalizable相比效率非常低。
如果我只想要10个字段代表普通数据类型,如整数或布尔值,那我肯定会使用Serializable。
但是现在我得到了更多的数据来存储和加载,例如,一个包含大约3.3百万字段的三维字节数组,我认为通过Serializable类实现的反射方式来保存数据是非常低效的。但是,由于我不能100%确定Exernalizable方式在存储这么大量的数据方面更加高效,我想在开始使用我的程序之前先确保自己,因为它不需要快速保存数据,但可以非常快速地加载数据(并且不只是一次,它需要首先进行一些计算,然后在程序中多次加载它,因为取决于程序在什么状态下它需要加载不同的数据集)。所以基本上我的想法是,我会通过异步多线程在Externalizable#readExternal()函数中加载字节数组。
请纠正我,如果我错了我认为在这里使用Exernalizable不是更有效的方式,因为我希望程序在加载数据时尽可能流畅地运行!
国王致敬,
法比安施密特!
基本上我现在所做的是比较通过反射/我自己的实现来保存/加载所花费的时间。
用于测试的代码:通过反射
主类(Comparision.class)
package de.cammeritz.chunksaver.util;
import java.io.File;
/**
* Created by F*/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.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Created by F*/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();
}
}
:通过我自己的实现
package de.cammeritz.chunksaver.util;
import java.io.Serializable;
/**
* Created by F*/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;
}
}
Seralization
基本上我可以同意@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方式。
但是这里有谁能告诉我为什么反射方式更快节省,以及如何提高自己保存数据的实现?
谢谢大家!
请指明*明确*你在哪里使用'Serializable'和你在哪里使用'Externalizable'。关于'使用反射'和'使用我自己的代码'这部分是没有意义的,因为你实际上同时使用了'Serializable'(通过'writeObject(byte [] [] [] [] [])'因此反射例如: – EJP
好吧lemme清楚说明我错误地解释了什么,我感到困惑的是,保存DataSerializable比保存DataExternalizable类快,但在相反的加载DataSerializable需要比加载DataExternalizable类更多的时间! –
如果你有一个新的问题,请通过点击[Ask Question](问问题)(https://*.com/questions/ask)按钮来提问。如果有助于提供上下文,请附上此问题的链接。/low-quality-posts/17679938) – EJoshuaS
易于测试和测量。 'Externalizable'不需要做所有'Serializable'的反射,但是在编码和维护方面还有很多工作要做。 – EJP
我认为'Serializable'很慢的想法相当古老。像7和8这样的现代JVM实现了大量的加速功能,以帮助'Serializable'运行得更快。我会从此开始,只有在事实上运行速度慢于可接受程度时才进一步调查。 – markspace
那么我认为最好的方法就是比较两种方法和时间来保存/加载数据。 –