BufferedWriter vs BufferedOutputStream 성능차이..

로그 데이터를 파일에 저장하기 위해서 BufferedWriter 클래스를 사용하다가, 갑자기 BufferedOutputStream으로 처리하는 것과의 성능상 차이에 대해서 확인하고 싶어서, 동일한 데이타를 파일에 저장해 봤다. 두 클래스의 성능 차이는 별로 없어 보이지만 그래도 확인 해 보자. 아래의 BufferWriterTest, BufferOutputStream 클래스의 buffersize는 1024로 동일하다.

– BufferWriterTest.java

import java.util.*;
import java.text.*;
import java.io.*;

public class BufferWriterTest {
	//
	static DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

	static String txt = "가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+ "가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라"
			+ "가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+ "가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+ "가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+ "가나다라마바사아자차타파하가나다라마바사아자차타파하" + "가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+ "가나다라마바사아자차타파하마바사아자차타파하";

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Date start = new Date();
		System.out.println("s – " + df.format(start));

		BufferedWriter bufferWriter;

		try {
			bufferWriter = new BufferedWriter(new FileWriter("c:\\BufferedWriter.txt", true), 1024);
			for (int i = 0; i < 5000000; i++) {
				bufferWriter.write(BufferWriterTest.txt);
				bufferWriter.newLine();
			}

			bufferWriter.flush();
			bufferWriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		Date end = new Date();
		System.out.println("e – " + df.format(end));
	}
}

결과(3.15G 파일 쓰기)

s – 2009-06-19 15:55:00:968
e – 2009-06-19 15:55:48:280

– BufferOutputStreamTest.java

import java.io.IOException;
import java.io.FileOutputStream;
import java.io.BufferedOutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class BufferOutputStreamTest {
	//
	static DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
	static String txt = "가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+ 	"가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라"
			+	"가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+ 	"가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+	"가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하" 
			+ "가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+ "가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하"
			+ "가나다라마바사아자차타파하가나다라마바사아자차타파하가나다라마바사아자차타파하" 
			+ 	"가나다라마바사아자차타파하마바사아자차타파하";

	/**
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		Date start = new Date();
		System.out.println("s – " + df.format(start));

		BufferedOutputStream bufferedOutput;
		try {
			bufferedOutput = new BufferedOutputStream(new FileOutputStream("c:\\BufferedStream.txt", true), 1024);

			for (int i = 0; i < 5000000; i++) {
				bufferedOutput.write(txt.getBytes());
				bufferedOutput.write("\n".getBytes());
			}
			bufferedOutput.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		Date end = new Date();
		System.out.println("e – " + df.format(end));
	}
}

결과(3.15G 파일 쓰기, )

s – 2009-06-19 15:56:41:889
e – 2009-06-19 15:58:19:825

위 결과를 보면, 비슷한 사이즈의 파일을 추가할 경우에 꽤 성능차이가 난다. 느낌에는 비슷한 성능을 낼 것으로 생각이 드는데, 스트링 처리는 Reader/Writer 시리즈가 더 적합하다는 것인가? 혹시 아래의 구조 때문에 그럴까요? 아시는 분은 조언을..

BufferedWriter BufferedOutputStream
java.lang.Object
– java.io.Writer
– java.io.BufferedWriter
java.lang.Object
– java.io.OutputStream
– java.io.FilterOutputStream
– java.io.BufferedOutputStream

BufferedWriter vs BufferedOutputStream 성능차이..”에 대한 2개의 생각

  1. 하늘빠

    님이 하신거는 두번째 BufferedOutputStream 에서 flush 를 안 했기 때문에.. 차이가 많이 나는듯 해요. 아래 코드로 하면.. 그리 차이가 안 나거든요. 파일 사이즈만 해도 그래요. 님이 하신 거는 두 파일의 사이즈가 다르죠..? 아직 메모리에 남아 있다는 증거에요.

    아래 코드로 하면 파일 사이즈는 두 방법 모두 3.9GB 이고요(바이트로 따져도 정확히 동일한 사이즈).. BufferedWriter 는 601 초, BufferedOutputStream 은 663초 나왔네요(님 컴퓨터가 성능이 제꺼 보다 좋은 모냥). 파일 생성되는 시간에서 차이가 날까봐 파일은 미리 만들었습니다. 아, 스트링도 미리 만들어둔 걸 동일하게 사용했어요. 스트링은 코드가 길어서 생략합니다.

    파일 생성 간격이 길어서 시스템 상태에 따라 퍼포먼스 측면에서 왔다갔다 하긴 하겠지만, 문자를 작업하는 경우라면 BufferedWriter 가 조금 더 빠른 것만은 분명할 거에요.

    두 클래스 조합간의 차이는, 파일 내용이 텍스트라면 char stream 을 사용하는 Writer 계열이, byte stream 을 사용하는 Stream 계열 보다 조금 빠르다(효율적이다) 라는 점입니다.

    bw = new BufferedWriter(new FileWriter(“/tmax/test1.txt”,true),1024);
    bos = new BufferedOutputStream(new FileOutputStream(“/tmax/test2.txt”,true),1024);

    Date start1 = new Date();
    System.out.println(“s1 – ” +df.format(start1));
    for(int i=0; i<5000000; i++){
    bw.write(txt);
    bw.newLine();
    }
    bw.flush();
    Date end1 = new Date();
    System.out.println("e1 - " +df.format(end1));

    Date start2 = new Date();
    System.out.println("s2 - " +df.format(start2));
    for(int i=0; i<5000000; i++){
    bos.write(txt.getBytes());
    bos.write("\n".getBytes());
    }
    bos.flush();
    Date end2 = new Date();
    System.out.println("e2 - " +df.format(end2));

    물론 상기 코드는 try ~ catch ~ finally 로 감쌌고 스트림은 모두 close() 했습니다.

    응답
    1. mcsong

      흠.. BufferedStream 코드에서 flush() 메쏘드를 빼먹었네요. ^^;; 말씀하신 쓰임세의 차이(캐릭터 기반과 스트림 기반)에 따라서 구분해서 잘 써야 겠지요.. ^^ 위 코드가 로깅을 위한 내용이고, 그러다 보니, Writer계열이 좀 좋게 나왔습니다. 좋은 댓글 감사드립니다. ^^

      응답

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.