본문 바로가기

Programming/JAVA

IO vs NIO performance compare (성능 비교)

Java 1.4 버전에서 이미 NIO가 나왔음에도 일반 IO 쓰는게 대부분이다.

이번에 IO와 NIO의 성능 비교를 하고자 파일 복사 테스트를 하였으니 참고 시 유용하게 쓰였으면 한다(단, 걸린 시간만 체크).


테스트조건

- Java 버전: jdk1.6.0_39

- 파일크기: 232 Mbytes (src.zip)

- 버퍼사이즈: 8192 bytes


(1~6번까지 하나씩 테스트)

공통

  1. private static File srcFile = new File("src.zip");  
  2. private static File desFile = new File("des.zip");  
  3. private static int bufferSize = 8192;  
  4.   
  5. public static void main(String[] args) {  
  6.     StopWatch sw = null;  
  7.     try {  
  8.         sw = new StopWatch("nio test");  
  9.         sw.start();  
  10.         // 1. IO  
  11.         io();  
  12.         // 2. Scatter/Gather  
  13.         scatterGather();  
  14.         // 3. MappedByteBuffer  
  15.         mapBuffer();  
  16.         // 4. FileChannel + ByteBuffer  
  17.         channel();  
  18.         // 5. ByteBuffer transferTo  
  19.         transferTo();  
  20.         // 6.ByteBuffer transferFrom  
  21.         transferFrom();  
  22.     } catch (Exception e) {  
  23.         e.printStackTrace();  
  24.     } finally {  
  25.         desFile.delete();  
  26.         sw.stop();  
  27.         System.out.println(sw.prettyPrint());  
  28.     }  
  29. }  


1. IO (걸린시간: 약 9.8초)

  1. public static void io() throws Exception {  
  2.     FileInputStream fis = new FileInputStream(srcFile);  
  3.     FileOutputStream fos = new FileOutputStream(desFile);  
  4.       
  5.     BufferedInputStream bis = new BufferedInputStream(fis, bufferSize);  
  6.     BufferedOutputStream bos = new BufferedOutputStream(fos, bufferSize);  
  7.       
  8.     int read = -1;  
  9.     while ((read = bis.read()) != -1) {  
  10.         bos.write(read);  
  11.     }  
  12.       
  13.     bos.close();  
  14.     bis.close();  
  15. }  
  16.   
  17. /* 파일복사 걸린시간 
  18. StopWatch 'nio test': running time (millis) = 9847 
  19. ----------------------------------------- 
  20. ms     %     Task name 
  21. ----------------------------------------- 
  22. 09847  100% 
  23. */  


2. NIO Scatter/Gather (걸린시간: 약 0.5초)

  1. public static void scatterGather() throws Exception {  
  2.     FileInputStream fis = new FileInputStream(srcFile);  
  3.     FileOutputStream fos = new FileOutputStream(desFile);  
  4.       
  5.     ScatteringByteChannel sbc = fis.getChannel();  
  6.     GatheringByteChannel gbc = fos.getChannel();  
  7.       
  8.     ByteBuffer bb = ByteBuffer.allocateDirect(bufferSize);  
  9.     while (sbc.read(bb) != -1) {  
  10.         bb.flip();  
  11.         gbc.write(bb);  
  12.         bb.clear();  
  13.     }  
  14.       
  15.     fos.close();  
  16.     fis.close();  
  17. }  
  18.   
  19. /* 파일복사 걸린시간 
  20. StopWatch 'nio test': running time (millis) = 468 
  21. ----------------------------------------- 
  22. ms     %     Task name 
  23. ----------------------------------------- 
  24. 00468  100% 
  25. */  


3. NIO MappedByteBuffer (걸린시간: 약 3초)

  1. public static void mapBuffer() throws Exception {  
  2.     FileInputStream fis = new FileInputStream(srcFile);  
  3.     FileOutputStream fos = new FileOutputStream(desFile);  
  4.       
  5.     FileChannel fcIn = fis.getChannel();  
  6.     FileChannel fcOut = fos.getChannel();  
  7.       
  8.     MappedByteBuffer mbb = fcIn.map(FileChannel.MapMode.READ_ONLY, 0, fcIn.size());  
  9.     fcOut.write(mbb);  
  10.       
  11.     fos.close();  
  12.     fis.close();  
  13. }  
  14.   
  15. /* 파일복사 걸린시간 
  16. StopWatch 'nio test': running time (millis) = 2995 
  17. ----------------------------------------- 
  18. ms     %     Task name 
  19. ----------------------------------------- 
  20. 02995  100% 
  21. */  


4. NIO FileChannel + ByteBuffer (걸린시간: 약 3.2초)

  1. public static void channel() throws Exception {  
  2.     FileInputStream fis = new FileInputStream(srcFile);  
  3.     FileOutputStream fos = new FileOutputStream(desFile);  
  4.       
  5.     FileChannel fcIn = fis.getChannel();  
  6.     FileChannel fcOut = fos.getChannel();  
  7.       
  8.     ByteBuffer bb = ByteBuffer.allocateDirect((int) fcIn.size());  
  9.     fcIn.read(bb);  
  10.       
  11.     bb.flip();  
  12.     fcOut.write(bb);  
  13.       
  14.     fos.close();  
  15.     fis.close();  
  16. }  
  17.       
  18. /* 파일복사 걸린시간 
  19. StopWatch 'nio test': running time (millis) = 3233 
  20. ----------------------------------------- 
  21. ms     %     Task name 
  22. ----------------------------------------- 
  23. 03233  100% 
  24. */  


5. NIO FileChannel transferTo (걸린시간: 약 2.8초)

  1. public static void transferTo() throws Exception {  
  2.     FileInputStream fis = new FileInputStream(srcFile);  
  3.     FileOutputStream fos = new FileOutputStream(desFile);  
  4.       
  5.     FileChannel fcIn = fis.getChannel();  
  6.     FileChannel fcOut = fos.getChannel();  
  7.       
  8.     fcIn.transferTo(0, fcIn.size(), fcOut); // Unix > Windows  
  9.       
  10.     fos.close();  
  11.     fis.close();  
  12. }  
  13.   
  14. /* 파일복사 걸린시간 
  15. StopWatch 'nio test': running time (millis) = 2823 
  16. ----------------------------------------- 
  17. ms     %     Task name 
  18. ----------------------------------------- 
  19. 02823  100% 
  20. */  


6. NIO FileChannel transferFrom (걸리시간: 약 2.9초)

  1. public static void transferFrom() throws Exception {  
  2.     FileInputStream fis = new FileInputStream(srcFile);  
  3.     FileOutputStream fos = new FileOutputStream(desFile);  
  4.       
  5.     FileChannel fcIn = fis.getChannel();  
  6.     FileChannel fcOut = fos.getChannel();  
  7.       
  8.     fcOut.transferFrom(fcIn, 0, fcIn.size()); // Unix < Windows  
  9.       
  10.     fos.close();  
  11.     fis.close();  
  12. }  
  13.   
  14. /* 파일복사 걸린시간 
  15. StopWatch 'nio test': running time (millis) = 2920 
  16. ----------------------------------------- 
  17. ms     %     Task name 
  18. ----------------------------------------- 
  19. 02920  100% 
  20. */