java文件序列化_通过快速Java和文件序列化加快速度
java文件序列化
從Java的第一個版本開始,許多開發人員每天都在努力實現至少與C / C ++一樣好的性能。 JVM供應商正在通過實現一些新的JIT算法來盡力而為,但仍有許多工作要做,尤其是在我們如何使用Java方面。
例如,對象<->文件序列化有很多優勢,尤其是在寫入/讀取可以輕松放入內存的對象方面。 我將嘗試闡明該主題。
所有測試都在下面顯示的簡單對象上執行:
為了更簡潔,我將僅顯示write方法(盡管另一種方法也非常相似)。 完整的源代碼可在我的GitHub(http://github.com/jkubrynski/serialization-tests)上找到。
最標準的Java序列化(我們都從這里開始)如下所示:
public void testWriteBuffered(TestObject test, String fileName) throws IOException {ObjectOutputStream objectOutputStream = null;try {FileOutputStream fos = new FileOutputStream(fileName);BufferedOutputStream bos = new BufferedOutputStream(fos);objectOutputStream = new ObjectOutputStream(bos);objectOutputStream.writeObject(test);} finally {if (objectOutputStream != null) {objectOutputStream.close();}} }加快標準序列化的最簡單方法是使用RandomAccessFile對象:
public void testWriteBuffered(TestObject test, String fileName) throws IOException {ObjectOutputStream objectOutputStream = null;try {RandomAccessFile raf = new RandomAccessFile(fileName, "rw");FileOutputStream fos = new FileOutputStream(raf.getFD());objectOutputStream = new ObjectOutputStream(fos);objectOutputStream.writeObject(test);} finally {if (objectOutputStream != null) {objectOutputStream.close();} }更復雜的技術是使用Kryo框架。 新舊版本之間的差異很大。 我都檢查了。 因為性能比較沒有發現任何明顯的不同,所以我將重點介紹第二個版本,因為它更加用戶友好,甚至更快。
private static Kryo kryo = new Kryo(); // version 2.xpublic void testWriteBuffered(TestObject test, String fileName) throws IOException {Output output = null;try {RandomAccessFile raf = new RandomAccessFile(fileName, "rw");output = new Output(new FileOutputStream(raf.getFD()), MAX_BUFFER_SIZE);kryo.writeObject(output, test);} finally {if (output != null) {output.close();}} }最后一個選擇是受Martin Thompson文章啟發的解決方案。 它顯示了如何以C ++方式和Java處理內存
public void testWriteBuffered(TestObject test, String fileName) throws IOException {RandomAccessFile raf = null;try {MemoryBuffer memoryBuffer = new MemoryBuffer(MAX_BUFFER_SIZE);raf = new RandomAccessFile(fileName, "rw");test.write(memoryBuffer);raf.write(memoryBuffer.getBuffer());} catch (IOException e) {if (raf != null) {raf.close();}} }TestObject的寫入方法如下所示:
public void write(MemoryBuffer unsafeBuffer) {unsafeBuffer.putLong(longVariable);unsafeBuffer.putLongArray(longArray);// we support nullsboolean objectExists = stringObject != null;unsafeBuffer.putBoolean(objectExists);if (objectExists) {unsafeBuffer.putCharArray(stringObject.toCharArray());}objectExists = secondStringObject != null;unsafeBuffer.putBoolean(objectExists);if (objectExists) {unsafeBuffer.putCharArray(secondStringObject.toCharArray());} }直接內存緩沖區類(簡稱,只是為了展示這個主意):
public class MemoryBuffer {// getting Unsafe by reflectionpublic static final Unsafe unsafe = UnsafeUtil.getUnsafe();private final byte[] buffer;private static final long byteArrayOffset = unsafe.arrayBaseOffset(byte[].class);private static final long longArrayOffset = unsafe.arrayBaseOffset(long[].class);// other offsets private static final int SIZE_OF_LONG = 8;// other sizes private long pos = 0;public MemoryBuffer(int bufferSize) {this.buffer = new byte[bufferSize];}public final byte[] getBuffer() {return buffer;}public final void putLong(long value) {unsafe.putLong(buffer, byteArrayOffset + pos, value);pos += SIZE_OF_LONG;}public final long getLong() {long result = unsafe.getLong(buffer, byteArrayOffset + pos);pos += SIZE_OF_LONG;return result;}public final void putLongArray(final long[] values) {putInt(values.length);long bytesToCopy = values.length << 3;unsafe.copyMemory(values, longArrayOffset, buffer, byteArrayOffset + pos, bytesToCopy);pos += bytesToCopy;}public final long[] getLongArray() {int arraySize = getInt();long[] values = new long[arraySize];long bytesToCopy = values.length << 3;unsafe.copyMemory(buffer, byteArrayOffset + pos, values, longArrayOffset, bytesToCopy);pos += bytesToCopy;return values;}/* other methods */ }卡尺運行多個小時的結果如下所示:
| 標準 | 207307 | 2362 |
| 英國皇家空軍的標準 | 42661 | 733 |
| KRYO 1.x | 12027 | 112 |
| KRYO 2.x | 11479 | 259 |
| 不安全 | 8554 | 91 |
最后我們可以得出一些結論:
- 不安全的序列化比標準使用java.io.Serializable的速度快23倍以上
- 使用RandomAccessFile可以將標準緩沖序列化速度提高近4倍
- Kryo動態序列化比手工實現的直接緩沖區慢約35%。
最后,正如我們所看到的,仍然沒有金錘。 對于我們很多人來說,獲得3000 ns(0.003ms)的時間不值得為我們要與文件序列化的每個對象編寫自定義實現。 對于標準解決方案,我們主要選擇Kryo。 但是,在低延遲系統中,100ns似乎是永恒的,選擇將完全不同。
翻譯自: https://www.javacodegeeks.com/2013/09/speed-up-with-fast-java-and-file-serialization.html
java文件序列化
總結
以上是生活随笔為你收集整理的java文件序列化_通过快速Java和文件序列化加快速度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Java 8之前,您编写了几行代码来对
- 下一篇: apache camel_使用Java的