JAVA IO效能比較
JAVA常用IO方式包括流,通道和MappedByteBuffer。
試驗通過複製一個大檔案(eclipse-jee-juno-SR2-win32.rar 237M),並選擇不同的緩衝區大小,記錄複製的時間。
影響IO的因素有很多,同樣的方式複製時間可能差異很大。所以需要排除一些最大和最小的資料,保證樣本的正確性。
將樣本資料Log.txt掛載為Oracle的外部表,以便分析
查詢樣本資料,發現同樣的方式,差異非常大。
SQL> select * from log where copytype='Channel' and buffersize='_1M';
COPYTYPE BUFFERSIZE COPYTIME
---------- ---------- ----------
Channel _1M 6896
Channel _1M 9859
Channel _1M 5711
Channel _1M 6514
Channel _1M 5400
Channel _1M 5494
Channel _1M 7052
Channel _1M 5807
Channel _1M 10904
Channel _1M 13839
Channel _1M 17035
Channel _1M 6255
Channel _1M 5085
已選擇13行。
整理樣本資料,將每種方式前五個資料和最後五個資料清除,並建立檢視。
此時資料已經相差不大。
SQL> select * from v1;
COPYTYPE BUFFERSIZE COPYTIME
---------- ---------- ----------
Channel _10M 807
Channel _10M 844
Channel _10M 870
Channel _1M 6255
Channel _1M 6514
Channel _1M 6896
Channel _50M 12748
Channel _50M 12865
Channel _50M 12901
Mapped _10M 11170
Mapped _10M 16355
Mapped _10M 17158
Mapped _1M 1774
Mapped _1M 1963
Mapped _1M 4213
Mapped _50M 472
Mapped _50M 601
Stream _10M 1047
Stream _10M 1182
Stream _10M 1436
Stream _1M 7283
Stream _1M 7347
Stream _50M 28280
Stream _50M 30288
Stream _50M 31012
已選擇25行。
使用行轉列,檢視平均時間。
COPYTYPE ONE TEN FIFTY
---------- ---------- ---------- ----------
Channel 6555 840.33 12838
Mapped 2650 14894.33 536.5
Stream 7315 1221.67 29860
試驗通過複製一個大檔案(eclipse-jee-juno-SR2-win32.rar 237M),並選擇不同的緩衝區大小,記錄複製的時間。
影響IO的因素有很多,同樣的方式複製時間可能差異很大。所以需要排除一些最大和最小的資料,保證樣本的正確性。
-
import java.io.BufferedInputStream;
-
import java.io.BufferedOutputStream;
-
import java.io.File;
-
import java.io.FileInputStream;
-
import java.io.FileOutputStream;
-
import java.io.IOException;
-
import java.io.RandomAccessFile;
-
import java.lang.reflect.InvocationHandler;
-
import java.lang.reflect.Method;
-
import java.lang.reflect.Proxy;
-
import java.nio.ByteBuffer;
-
import java.nio.MappedByteBuffer;
-
import java.nio.channels.FileChannel;
-
import java.nio.channels.FileChannel.MapMode;
-
import java.util.Date;
-
-
public class TestIO {
-
// 快取大小
-
private static enum BufferSize {
-
_1M, _10M, _50M;
-
-
public static int getBufferSize(BufferSize bufferSize) {
-
if ("_1M".equals(bufferSize.toString())) {
-
return 1024 * 1024;
-
} else if ("_10M".equals(bufferSize.toString())) {
-
return 10 * 1024 * 1024;
-
} else if ("_50M".equals(bufferSize.toString())) {
-
return 50 * 1024 * 1024;
-
}
-
return -1;
-
}
-
}
-
-
// 原始檔
-
private static File source = new File("C:/Users/lihuilin/Desktop/eclipse-jee-juno-SR2-win32.rar");
-
-
// 複製檔案介面
-
private static interface Copy {
-
void action() throws Exception;
-
-
BufferSize getBufferSize();
-
}
-
-
// 獲取目標檔案
-
private static File getTarget(Copy copy, BufferSize bufferSize) {
-
String target = "C:/tmp/" + copy.getClass().getSimpleName() + bufferSize.toString() + "_" + new Date().getTime() + ".rar";
-
return new File(target);
-
}
-
-
// 傳統IO流複製方式
-
private static class Stream implements Copy {
-
BufferSize bufferSize;
-
-
public Stream(BufferSize bufferSize) {
-
this.bufferSize = bufferSize;
-
}
-
-
@Override
-
public void action() throws IOException {
-
BufferedInputStream in = new BufferedInputStream(new FileInputStream(source), BufferSize.getBufferSize(bufferSize));
-
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(getTarget(this, bufferSize)));
-
byte[] buffer = new byte[BufferSize.getBufferSize(bufferSize)];
-
int length;
-
while ((length = in.read(buffer)) != -1) {
-
out.write(buffer, 0, length);
-
}
-
out.flush();
-
in.close();
-
out.close();
-
}
-
-
@Override
-
public BufferSize getBufferSize() {
-
return bufferSize;
-
}
-
}
-
-
// NIO通道方式
-
private static class Channel implements Copy {
-
-
private BufferSize bufferSize;
-
-
public Channel(BufferSize bufferSize) {
-
this.bufferSize = bufferSize;
-
}
-
-
@Override
-
public void action() throws Exception {
-
FileChannel in = new FileInputStream(source).getChannel();
-
FileChannel out = new FileOutputStream(getTarget(this, bufferSize)).getChannel();
-
ByteBuffer buffer = ByteBuffer.allocate(BufferSize.getBufferSize(bufferSize));
-
while (in.read(buffer) != -1) {
-
buffer.flip();
-
out.write(buffer);
-
buffer.compact();
-
}
-
in.close();
-
out.close();
-
}
-
-
@Override
-
public BufferSize getBufferSize() {
-
return bufferSize;
-
}
-
}
-
-
// MappedByteBuffer方式
-
private static class Mapped implements Copy {
-
private BufferSize bufferSize;
-
-
public Mapped(BufferSize bufferSize) {
-
this.bufferSize = bufferSize;
-
}
-
-
@Override
-
public void action() throws Exception {
-
FileChannel in = new RandomAccessFile(source, "r").getChannel();
-
FileChannel out = new RandomAccessFile(getTarget(this, bufferSize), "rw").getChannel();
-
long pos = 0;
-
long step = BufferSize.getBufferSize(bufferSize);
-
MappedByteBuffer inBuffer, outBuffer = null;
-
while (pos < in.size() && (in.size() - pos) > step) {
-
inBuffer = in.map(MapMode.READ_ONLY, pos, BufferSize.getBufferSize(bufferSize));
-
outBuffer = out.map(MapMode.READ_WRITE, pos, BufferSize.getBufferSize(bufferSize));
-
outBuffer.put(inBuffer);
-
pos = pos + step;
-
inBuffer.clear();
-
outBuffer.clear();
-
}
-
-
inBuffer = in.map(MapMode.READ_ONLY, pos, in.size() - pos);
-
outBuffer = out.map(MapMode.READ_WRITE, pos, in.size() - pos);
-
-
outBuffer.put(inBuffer);
-
inBuffer.clear();
-
outBuffer.clear();
-
in.close();
-
out.close();
-
}
-
-
@Override
-
public BufferSize getBufferSize() {
-
return bufferSize;
-
}
-
-
}
-
-
// 動態代理,用於記錄複製時間並寫入日誌
-
private static class Watch implements InvocationHandler {
-
private Copy copy;
-
-
public Watch(Copy copy) {
-
this.copy = copy;
-
}
-
-
public Copy getInstance() {
-
return (Copy) Proxy.newProxyInstance(copy.getClass().getClassLoader(), copy.getClass().getInterfaces(), this);
-
}
-
-
@Override
-
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-
Object result;
-
long start = System.currentTimeMillis();
-
result = method.invoke(copy, args);
-
long end = System.currentTimeMillis();
-
-
String log = copy.getClass().getSimpleName() + ":" + copy.getBufferSize().toString() + ":" + (end - start) + "\n";
-
System.out.print(log);
-
FileOutputStream out = new FileOutputStream("C:/tmp/Log.txt", true);
-
out.write(log.getBytes());
-
out.flush();
-
out.close();
-
return result;
-
}
-
}
-
-
public static void main(String[] args) throws Exception {
-
for (int i = 0; i < 15; i++) {
-
new Watch(new Mapped(BufferSize._50M)).getInstance().action();
-
new Watch(new Mapped(BufferSize._10M)).getInstance().action();
-
new Watch(new Mapped(BufferSize._1M)).getInstance().action();
-
-
new Watch(new Channel(BufferSize._50M)).getInstance().action();
-
new Watch(new Channel(BufferSize._10M)).getInstance().action();
-
new Watch(new Channel(BufferSize._1M)).getInstance().action();
-
-
new Watch(new Stream(BufferSize._50M)).getInstance().action();
-
new Watch(new Stream(BufferSize._10M)).getInstance().action();
-
new Watch(new Stream(BufferSize._1M)).getInstance().action();
-
}
-
}
- }
-
create table log
-
(
-
copytype varchar2(10),
-
buffersize varchar2(10),
-
copytime varchar2(10)
-
)
-
organization external
-
(
-
type oracle_loader
-
default directory tmp
-
access parameters
-
(
-
records delimited by "\n"
-
FIELDS TERMINATED BY ":" LDRTRIM
-
REJECT ROWS WITH ALL NULL FIELDS
-
(
-
copytype CHAR(20) TERMINATED BY ":",
-
buffersize CHAR(20) TERMINATED BY ":",
-
copytime CHAR(20) TERMINATED BY ":"
-
)
-
)
-
location ('Log.txt')
- );
SQL> select * from log where copytype='Channel' and buffersize='_1M';
COPYTYPE BUFFERSIZE COPYTIME
---------- ---------- ----------
Channel _1M 6896
Channel _1M 9859
Channel _1M 5711
Channel _1M 6514
Channel _1M 5400
Channel _1M 5494
Channel _1M 7052
Channel _1M 5807
Channel _1M 10904
Channel _1M 13839
Channel _1M 17035
Channel _1M 6255
Channel _1M 5085
已選擇13行。
整理樣本資料,將每種方式前五個資料和最後五個資料清除,並建立檢視。
-
create or replace view v1 as
-
select copytype,buffersize,copytime from
-
(
-
select copytype,buffersize,copytime,
-
row_number() over(partition by copytype,buffersize order by to_number(copytime)) c1,
-
row_number() over(partition by copytype,buffersize order by to_number(copytime) desc) c2
-
from log
- ) log where c1 not in (1,2,3,4,5) and c2 not in(1,2,3,4,5);
SQL> select * from v1;
COPYTYPE BUFFERSIZE COPYTIME
---------- ---------- ----------
Channel _10M 807
Channel _10M 844
Channel _10M 870
Channel _1M 6255
Channel _1M 6514
Channel _1M 6896
Channel _50M 12748
Channel _50M 12865
Channel _50M 12901
Mapped _10M 11170
Mapped _10M 16355
Mapped _10M 17158
Mapped _1M 1774
Mapped _1M 1963
Mapped _1M 4213
Mapped _50M 472
Mapped _50M 601
Stream _10M 1047
Stream _10M 1182
Stream _10M 1436
Stream _1M 7283
Stream _1M 7347
Stream _50M 28280
Stream _50M 30288
Stream _50M 31012
已選擇25行。
使用行轉列,檢視平均時間。
-
select copytype,
-
round(avg(decode(buffersize,'_1M',copytime)),2) one,
-
round(avg(decode(buffersize,'_10M',copytime)),2) ten,
-
round(avg(decode(buffersize,'_50M',copytime)),2) fifty
- from v1 group by copytype;
---------- ---------- ---------- ----------
Channel 6555 840.33 12838
Mapped 2650 14894.33 536.5
Stream 7315 1221.67 29860
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-776173/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 雲主機的硬碟IO效能比較硬碟
- Java中List集合效能比較Java
- Java Bean Copy元件的效能比較JavaBean元件
- Java JIT與AOT效能比較 - foojayJava
- 效能比較
- Java幾種常用JSON庫效能比較JavaJSON
- Java基礎(二)- 普通for迴圈、foreach效能比較Java
- Java 比較器Java
- python 批量resize效能比較Python
- JAVA中生成隨機數Random VS ThreadLocalRandom效能比較Java隨機randomthread
- Java實體對映工具MapStruct 與BeanUtils效能比較JavaStructBean
- 請比較下for、forEach、for of的效能的效能
- 排序演算法效能比較排序演算法
- java比較日期大小Java
- Java和JavaSciprt比較Java
- java--BEAN比較JavaBean
- 比較Java與Node.js的併發性和效能- maxantJavaNode.js
- IocPerformance 常見IOC 功能、效能比較ORM
- 堆排序和快速排序效能比較排序
- Java的BigDecimal比較大小JavaDecimal
- WCF與ASP.NET Core效能比較ASP.NET
- PostgreSQL、Redis與Memcached的效能比較 - CYBERTECSQLRedis
- Java 字串比較、拼接問題Java字串
- Java 中 Comparable 和 Comparator 比較Java
- Java字串建立方式比較Java字串
- Apache與Nginx的優缺點、效能比較,到底選擇哪個比較好?ApacheNginx
- PHP file_get_contents 與 curl 效能比較PHP
- Python、JavaScript和Rust的Web效能比較 - AlexPythonJavaScriptRustWeb
- Spring Boot Native vs Go:效能比較 – Ignacio SuaySpring BootGo
- 使用 BenchmarkDotNet 比較指定容量的 List 的效能
- Caddy 與 Nginx的基準效能比較 - tjllNginx
- MySQL 中的 distinct 和 group by 的效能比較MySql
- java double、float型別的比較Java型別
- 雲原生Java與Golang比較 -lgorJavaGolang
- 【Java】浮點數相等性比較Java
- 常用的Java開發工具比較Java
- java高效能反射及效能對比Java反射
- 四個id 生成器效能比較記錄
- NATS訊息傳遞與REST效能比較 | VinsguruREST