본문 바로가기
  • 개발하는 곰돌이
Algorithm/관련내용

[Kotlin] 코틀린으로 알고리즘 문제를 풀 때 출력 방식별 속도에 대하여

by 개발하는 곰돌이 2023. 1. 20.
 

[Kotlin] 백준 23309 : 철도 공사

문제 링크 23309번: 철도 공사 첫 번째 줄에 공사를 시작하기 이전에 있는 역의 개수를 나타내는 양의 정수 $N$과 공사 횟수를 나타내는 양의 정수 $M$이 주어진다. ($1 \le N \le 500\,000$, $1 \le M \le 1\,500

colabear754.tistory.com

위 링크의 문제풀이에서 BufferedWriter를 사용한 풀이는 시간 초과로 통과에 실패했는데 StringBuilder로 문자열을 하나로 만들어 출력한 풀이는 통과에 성공했다고 얘기한 적이 있다. 기본적으로 코틀린은 자바의 함수와 클래스를 사용하여 출력하기 때문에 백준님이 측정한 출력 방식별 속도 측정을 기반으로 문제를 풀고 있었다. 그래서 BufferedWriter가 StringBuilder보다 빠른 것으로 알고 있었는데 정반대의 결과가 나온것이 의아해서 직접 속도를 테스트 해보기로 했다.

 

측정 방식은 백준님의 측정 방식과 동일하게 각 출력방식별로 1부터 10,000,000까지의 수를 한 줄에 하나씩 출력하는 시간을 10번 측정하여 평균값을 계산하는 방식이다.

 

결과 요약


1. BufferedWriter(문자열 템플릿)

코드가 깔끔하고 BufferedWriter가 가장 빠르다고 알려져 있어서 평소에 가장 많이 쓰는 방법이다. 평균적으로 약 2827 밀리초의 시간이 걸렸다.

for (i in 1..10000000) {
    write("$i\n")
}
flush()


2. BufferedWriter(toString() + \n)

이 방식을 포함한 다른 BufferedWriter를 사용한 방법은 한번도 써보진 않았는데 팀장님이 얘기를 해주셔서 테스트 해보았다. 평균적으로 약 2820 밀리초의 시간이 걸렸다.

for (i in 1..10000000) {
    write(i.toString() + "\n")
}
flush()


3. BufferedWriter(toString() + newLine())

줄바꿈을 newLine()으로 한 방식이다. 평균적으로 약 2939 밀리초의 시간이 걸렸다.

for (i in 1..10000000) {
    write(i.toString())
    newLine()
}
flush()


4. BufferedWriter(toString() + \n) 2번째 방식

2번 방식처럼 toString()\n을 사용하긴 하지만 문자열의 덧셈을 사용하지 않고 각각 write()를 한 방식이다. 평균적으로 약 2897 밀리초의 시간이 걸렸다.

for (i in 1..10000000) {
    write(i.toString())
    write("\n")
}
flush()


5. StringBuilder(문자열 템플릿)

append()로 정수와 개행문자의 문자열 템플릿을 추가하여 출력한 방식이다. 평균적으로 약 3177 밀리초의 시간이 걸렸다.

for (i in 1..10000000) {
    sb.append("$i\n")
}
print(sb)


6. StringBuilder(append().append())

append()로 정수를 추가하고 다시 한 번 append()로 개행 문자를 추가하여 줄바꿈을 한 방식이다. 평균적으로 약 3120 밀리초의 시간이 걸렸다.

for (i in 1..10000000) {
    sb.append(i).append('\n')
}
print(sb)


7. println()

정말 단순하게 println()으로 출력한 방식이다. 이 방식은 출력할 결과가 하나만 있는 경우가 아니면 쓰지 않는 방식이다. 평균적으로 약 17672 밀리초의 시간이 걸렸다.

for (i in 1..10000000) {
    println(i)
}


결과 요약


여담

측정 결과도 분명히 BufferedWriter를 사용하는 것이 StringBuilder보다 미세하게 더 빠른데 정작 해당 문제는 BufferedWriter는 시간초과가 뜨고 StringBuilder(append().append())를 쓰면 통과되는 정 반대의 결과가 나온다. 결국 의문만 더 커져버렸다...

댓글