Java/Tip & Tech2009. 11. 26. 10:34

요즘 회사 프로젝트로 인해서 Java NIO를 공부하고 있다.

Java NIO에 포함되어 있는 Buffer, Channel, Selector 등의 특징들 중에

Buffer에 관하여 공부를 하던 중, ByteBufferPool에서 초기화 부분에서

김성박, 송지훈님의 "자바 I/O & NIO 네트워크 프로그래밍"에서 다른 소스들과는

다른 방법을 사용하고 있어서 JRE 1.6, activemq v1.5, jetty v4.2.9, manta v1.9등에 포함되어 있는

방식과 비교하여 속도를 비교해 보았다.



1. 반복문을 통한 Direct ByteBuffer 생성


 4096 크기의 Direct ByteBuffer 10000개를 만들어서 ArrayList 타입의 공간에 담는 경우를 생각해보자.

필자가 생각한 방법도 반복문을 돌면서 Direct ByteBuffer를 생성하는 방법이다.-_-;


import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

public class TestByteBufferAllocateDirect1 {
	public static void main(String[] args) {
		int buffCount = 10000;
		int buffSize = 4096;
		List queue = new ArrayList();

		long startTimeMillis = System.currentTimeMillis();

		for (int i = 0; i < buffCount; i++) {
			queue.add(ByteBuffer.allocateDirect(buffSize));
		}

		System.out.println("***** Direct ByteBuffer 생성 완료!!! *****");
		System.out.println("생성된 ByteBuffer 수 : " + queue.size());
		System.out.println("생성 소요 시간 : " + ((System.currentTimeMillis() - startTimeMillis)));
	}
}


위 소스로 세번 실행한 결과는 아래와 같다.

***** Direct ByteBuffer 생성 완료!!! *****
생성된 ByteBuffer 수 : 10000
생성 소요 시간 : 291

***** Direct ByteBuffer 생성 완료!!! *****
생성된 ByteBuffer 수 : 10000
생성 소요 시간 : 290

***** Direct ByteBuffer 생성 완료!!! *****
생성된 ByteBuffer 수 : 10000
생성 소요 시간 : 311

평균 : 297 ms




2. 하나의 Direct ByteBuffer 생성 후, slice()로 나누기


위에서 언급한 책에 나와 있는 방법을 이용한 소스는 아래와 같다.

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

public class TestByteBufferAllocateDirect2 {
	public static void main(String[] args) {
		int buffCount = 10000;
		int buffSize = 4096;
		List queue = new ArrayList();

		long startTimeMillis = System.currentTimeMillis();

		ByteBuffer buffer = ByteBuffer.allocateDirect(buffSize * buffCount);

		int position = 0;
		for (int i = 0; i < buffCount; i++) {
			int max = position + buffSize;
			buffer.limit(max);
			queue.add(buffer.slice());
			position = max;
			buffer.position(position);
		}

		System.out.println("***** Direct ByteBuffer 생성 완료!!! *****");
		System.out.println("생성된 ByteBuffer 수 : " + queue.size());
		System.out.println("생성 소요 시간 : " + ((System.currentTimeMillis() - startTimeMillis)));
	}
}


위 소스로 세번 실행한 결과는 아래와 같다.

***** Direct ByteBuffer 생성 완료!!! *****
생성된 ByteBuffer 수 : 10000
생성 소요 시간 : 120

***** Direct ByteBuffer 생성 완료!!! *****
생성된 ByteBuffer 수 : 10000
생성 소요 시간 : 151

***** Direct ByteBuffer 생성 완료!!! *****
생성된 ByteBuffer 수 : 10000
생성 소요 시간 : 150

평균 : 140 ms



평균 시간을 비교해 보면 2번의 방법이 1번의 방법에 절반도 안되는 시간만이 소요된다는 것을 알 수 있다.


여러 문서에 나와 있듯이 Direct ByteBuffer의 생성은 가벼운 작업이 아니다.

그렇기 때문에 여러개의 Direct ByteBuffer를 사용할 때는 그때 그때 생성하여 사용하는 것이 아니라

ByteBufferPool을 생성하여 사용하는 경우가 많다. 그럴때, 적용하면 상당히 유용할만한 소스이다.


아래 이미지는 블로그에 "책 소개" 메뉴를 만들고 싶은 욕심이 생기게 하는 책...

이번에 참고한 김성박, 송지훈님의 "자바 I/O & NIO 네트워크 프로그래밍" 이다.

<< 출처 : Yes24 >>

Posted by Huikyun