※이 문서는 『Java Performance and Scalability Volume1』(by Dov Bulka)라는 책의
5장:I/O Streams 를 읽고 나름대로 정리한 것입니다.
Preface |
자바의 I/O stream은 socket, file, string, character array 등등을 끝단으로 해서 데이터를 읽고 쓸 수 있다. 이러한 I/O 들의 성능 문제를 언급하기 위해서 전체를 다 다룰 필요는 없을 것 같다. 우리가 원하는 것은 실제 I/O 장치와 stream 클래스와의 상호작용의 기본적인 성능 원리를 이해하는 것이므로 file I/O에 관한 stream을 살펴보는 것만으로도 충분할 것이다. Java에서 I/O stream을 이용하여 데이터를 읽고 쓰는데 있어서 가장 중요한 문제는 버퍼링과 유니코드 변환 문제이다. 이번 장에서 다루는 모든 최적화는 둘중의 하나이다.
Example I/O Code |
이번장에서 사용하는 예제들은 I/O stream을 통해 주로 데이타를 읽기만 하거나 쓰기만 할 것이므로 쓰여질 데이터가 될 코드를 미리 작성해 둔다. 간단한 주식거래에 대한 클래스로 거래 날짜, 매도(매수), 주식 심볼, 거래 주식수, 주식 가격만을 정보로 가진다고 하자. 그러면 대충 필요한 겉모양은 나온다.
class Trade{
String date;
boolean buy;
int numShares;
String symbol;
float price;
...
}
Trade 객체를 파일에 기록한다면 (1)이나 (2)처럼 사용할 것이다.
(1) Trade buy = new Trade(“
fw.println(buy); //fw is a FileWriter
(2) fos.write(buy.toString().getBytes()); //fos is FileOutputStream
println() 메소드는 Trade.toString()을 호출할텐데 이는 다소 비싼 작업이다. 여기에서는 I/O 의 성능에 관해서 이야기를 할 것이므로 이러한 부분들이 성능 비교에 별 영향을 미치지 못하도록 클래스를 적절히 수정하도록 하겠다. 생성자에서 String이나 byte로 미리 변환을 시켜놓고 toString()이나 toBytes() 메소드는 단지 이에 대한 레퍼런스 값만을 넘기게 함으로써 I/O 작업을 위해 String값이나 byte값을 매번 요구하더라도 값을 넘겨주는 작업은 성능에 거의 영향을 미치지 않게 된다. 코드는 아래와 같다.
class Trade{
String date;
boolean buy;
int numShares;
String symbol;
float price;
String stringRep;
byte[] byteRep;
public Trade(String d, boolean b, int n, String s, float p){
symbol = s;
numShares = n;
buy = b;
date = d;
price = p;
StringRep = privateToString(); //String으로 미리 변환
byteRep = stringRep.getBytes(); //byte로 미리 변환
}
private String privateToString(){
StringBuffer sb = new StringBuffer(128);
sb.append(date).append(“ ”);
if(buy) sb.append(“Buy “);
else sb.append(“Sell “);
sb.append(numShared).append(“ ”);
sb.append(symbol).append(“ ”);
sb.append(price).append(“ ”);
return sb.toString();
}
public String toString(){
return stringRep;
}
public byte[] toBytes(){
return byteRep;
}
}
1. Output Buffering |
버퍼링은 바이트당 오버헤드를 최소화 할 수 있는 기법이다. 데이터를 보내기 위해서 자바에서는 OS 자체의 함수를 콜해야 하는데, OS 함수 자체는 한번 콜하는데 드는 비용이 한 바이트를 보내나 여러 바이트를 보내나 비슷하다(그 비용 또한 만만치도 않다). 그러므로 한번에 한 바이트씩만 보낸다면 여러 바이트를 묶어서 한번에 보내는 것보다 엄청나게 비싼 댓가를 치러야 되는 것은 자명한 사실이다. 자바에서 I/O stream을 이용해서 버퍼링을 하는 것은 아주 쉽다. 단지 원래의 output stream을 buffered stream으로 감싸기만 하면 된다.
여기에서는 Trade 객체를 FileOutputStream을 이용해서 파일에 기록할 때 버퍼링이 얼마나 나은 결과를 가져 오는지 보여주고자 한다. 첫번째 예제는 버퍼링 없이 FileOutputStream을 사용하였고 두번째 예제는 버퍼링을 사용하였다.
[예제1] 수행시간 : 33초
Trade buy = new Trade(“
Trade sel = new Trade(“
FileOutputStream fos = new FileOutputStream(“stock.dat”);
for(int i=0; i<1000000; i++){
'Dev... > 플밍 관련 자료' 카테고리의 다른 글
[펌] ANT (상): Ant 무엇에 쓰는 물건인고? (0) | 2005.02.11 |
---|---|
[펌] ANT (하): Ant 무엇에 쓰는 물건인고? (0) | 2005.02.11 |
[펌] Java Garbage Collection에 대한 소개와 메모리 Tuning을 통한 성능향상 (0) | 2005.01.07 |
[펌] 이름별 소팅에 관한 SQL 쿼리 (0) | 2004.10.21 |
[펌] 드디어 mono 베타1이 릴리즈되었습니다. (2) | 2004.05.06 |