Re: [分享] java nio performance tuning

看板java作者 (AIIA)時間11年前 (2013/10/06 17:04), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串6/6 (看更多)
※ 引述《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)
文章代碼(AID): #1IKIUd9X (java)
文章代碼(AID): #1IKIUd9X (java)