作者AI3767 (AIIA)
看板java
标题Re: [分享] java nio performance tuning
时间Sun Oct 6 17:04:35 2013
※ 引述《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)