Re: [分享] java nio performance tuning
※ 引述《sbrhsieh (十年一夢)》之銘言:
恕刪
看完你的測試, 原來還有個block的讀取方式, 是我沒有考量到的
前面我的測試中說的, 單純 read byte 是只讀取1個 byte
先說結論好了
我增加了 一次讀取一個區塊 的測試, S2的讀取效率確實又大幅增進
以一般不是太大的檔案來說, 比起S3的方式, 時間上差不多
甚至, S3因為為了區塊讀取, 所增加code的部分還多花了點時間
使得 S3 還比 S2 輕微慢了點
為什麼這麼說呢, 因為, 當以較大的檔案做同樣的測試時, S3 就會比S2快一丁點
確實, 沒有過大的幅度的差異, 只是差異已經可以確認觀察出來
也的確, 沒有原以為的那樣大的增進, 以1.6G來說, 增進不到 20% 吧
S2以區塊讀取: 2.02 秒
S3以區塊讀取: 1.728
到這邊, 我不把code附上, 就顯得太沒誠意了 XD
不過, 修改了只留下針對 S2, S3 對 一次一byte讀取,以及區塊讀取 的部分
[GenNIOData.java] 生成測試檔用
import java.io.*;
import java.util.Random;
public class GenNIOData {
private static final Random rand = new Random();
//COUNT*4*16 = 1671901184 COUNT*16 = 417975296
public static int COUNT = 26123456;
public static int MULT = 16;
public static void main(String[] args) throws Exception {
//MULT = 1;
outBin("ip_16.bin", MULT); //ip.bin ; ip_16.bin
}
/** Create 4 * COUNT bytes */
static void outBin(String fName, int mul) throws Exception {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(fName));
DataOutputStream dos = new DataOutputStream(bos);
int total = COUNT * mul;
for(int i=total; i>0; i--) {
int ip = rand.nextInt(255);
for(int p=0; p<3; p++) ip = ip<<8 | rand.nextInt(255);
dos.writeInt(ip);
}
dos.close();
}
}
[NIOTest.java] 執行測試用
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
public class NIOTest {
static int[] ipArr = new int[GenNIOData.COUNT]; // size of MULT==1
static StringBuilder msg = new StringBuilder();
static int bufferSize = ipArr.length; //ipArr.length ; 64*1024
static int testVer = 1;
public static void main(String[] args) throws Exception {
int testCount = 1;
String fName = "ip_16.bin"; // ip.bin ; ip_16.bin
for(int i=testCount; i>0; i--) {
testS2(fName);
testS3(fName);
}
System.out.println(msg.toString());
}
static void outMsg(String m) { msg.append(m+"\n"); }
static int toIpArr(byte[] bArr, int len) {
int count = 0;
for(int i=0; i<len; ) {
int ip = bArr[i++]&0xFF;
ip = ip<<8 | bArr[i++]&0xFF;
ip = ip<<8 | bArr[i++]&0xFF;
ip = ip<<8 | bArr[i++]&0xFF;
ipArr[count++] = ip;
}
return count;
}
static void testS2(String fName) throws Exception {
outMsg("Strategt 2 -->");
long startTime = System.currentTimeMillis();
FileInputStream fis = new FileInputStream(new File(fName));
BufferedInputStream bis = new BufferedInputStream(fis, bufferSize);
DataInputStream dis = new DataInputStream(bis);
int offset = 0;
int counter = 0;
byte[] bArr = new byte[bufferSize<<2];
//outMsg("bArr size: "+bArr.length);
//outMsg("ipArr size: "+ipArr.length);
try {
while(true) {
//ipArr[counter++] = dis.readInt(); //original version only for MULT==1
//dis.readByte(); //read byte version
//offset++;
int len = dis.read(bArr, 0, bArr.length); //read block version
//counter += toIpArr(bArr, len);
if( len<0 ) break;
//offset += len;
}
} catch(EOFException e){
} finally {
long endTime = System.currentTimeMillis();
outMsg("offset:"+offset+" count"+counter+" took: "+
(endTime-startTime)/1000.0F);
dis.close();
}
}
static void testS3(String fName) throws IOException {
outMsg("Strategt 3 -->");
long startTime = System.currentTimeMillis();
FileInputStream fis = new FileInputStream(new File(fName));
FileChannel channel = fis.getChannel();
ByteBuffer bb = ByteBuffer.allocateDirect(ipArr.length<<2);
bb.clear();
byte[] bArr = new byte[bufferSize<<2];
//outMsg("channel size: "+channel.size()/4);
//outMsg("bArr size: "+bArr.length);
//outMsg("ipArr size: "+ipArr.length);
long len = 0;
int offset = 0;
int counter = 0;
while((len=channel.read(bb))!=-1) {
bb.flip();
//int numData = (int)(len>>2); //original verion only for MULT==1
//IntBuffer ib = bb.asIntBuffer();
//ib.get(ipArr, offset, numData);
//counter += numData;
//for(; len>0; len--) { //read byte version
// bb.get();
// offset++;
//}
int remain = (int)len; //read block version
while(remain>0) {
int needLen = remain>bArr.length? bArr.length: remain;
bb.get(bArr, 0, needLen);
//counter += toIpArr(bArr, needLen);
remain -= needLen;
//offset += needLen;
}
bb.clear();
}
long endTime = System.currentTimeMillis();
outMsg("offset:"+offset+" count"+counter+" took: "+
(endTime-startTime)/1000.0F);
}
}
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.45.188.160
※ 編輯: AI3767 來自: 114.45.188.160 (10/06 17:09)
討論串 (同標題文章)
完整討論串 (本文為第 6 之 6 篇):
java 近期熱門文章
PTT數位生活區 即時熱門文章