2017-10-19 84 views
0

好的,在我回到我的問題之前,我想先指出我知道Serializable和Exernalizable之間的區別,所以你不需要給出解釋!可擴展數據集的可序列化或可擴展性,哪個更快更實用?

我基本上試圖做的是將一個類的所有數據保存在一個文件中。 我們已經到了Java 9出來的時候,JVM速度非常快,但仍然有人(我認爲他們的觀點)認爲使用Serializable處理大量數據的效率與使用Exernalizable相比效率非常低。

如果我只想要10個字段代表普通數據類型,如整數或布爾值,那我肯定會使用Serializable。

但是現在我得到了更多的數據來存儲和加載,例如,一個包含大約3.3百萬字段的三維字節數組,我認爲通過Serializable類實現的反射方式來保存數據是非常低效的。但是,由於我不能100%確定Exernalizable方式在存儲這麼大量的數據方面更加高效,我想在開始使用我的程序之前先確保自己,因爲它不需要快速保存數據,但可以非常快速地加載數據(並且不只是一次,它需要首先進行一些計算,然後在程序中多次加載它,因爲取決於程序在什麼狀態下它需要加載不同的數據集)。所以基本上我的想法是,我會通過異步多線程在Externalizable#readExternal()函數中加載字節數組。

請糾正我,如果我錯了我認爲在這裏使用Exernalizable不是更有效的方式,因爲我希望程序在加載數據時儘可能流暢地運行!

國王致敬,

法比安施密特!

+1

易於測試和測量。 'Externalizable'不需要做所有'Serializable'的反射,但是在編碼和維護方面還有很多工作要做。 – EJP

+1

我認爲'Serializable'很慢的想法相當古老。像7和8這樣的現代JVM實現了大量的加速功能,以幫助'Serializable'運行得更快。我會從此開始,只有在事實上運行速度慢於可接受程度時才進一步調查。 – markspace

+0

那麼我認爲最好的方法就是比較兩種方法和時間來保存/加載數據。 –

回答

-1

基本上我現在所做的是比較通過反射/我自己的實現來保存/加載所花費的時間。

用於測試的代碼:通過反射

主類(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.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(); 
    } 
} 
:通過我自己的實現

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; 
    } 

} 

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方式。

但是這裏有誰能告訴我爲什麼反射方式更快節省,以及如何提高自己保存數據的實現?

謝謝大家!

+0

請指明*明確*你在哪裏使用'Serializable'和你在哪裏使用'Externalizable'。關於'使用反射'和'使用我自己的代碼'這部分是沒有意義的,因爲你實際上同時使用了'Serializable'(通過'writeObject(byte [] [] [] [] [])'因此反射例如: – EJP

+0

好吧lemme清楚說明我錯誤地解釋了什麼,我感到困惑的是,保存DataSerializable比保存DataExternalizable類快,但在相反的加載DataSerializable需要比加載DataExternalizable類更多的時間! –

+3

如果你有一個新的問題,請通過點擊[Ask Question](問問題)(https://stackoverflow.com/questions/ask)按鈕來提問。如果有助於提供上下文,請附上此問題的鏈接。/low-quality-posts/17679938) – EJoshuaS