기록/JAVA

[JAVA] 예외처리의 비용

5월._. 2022. 4. 30.
728x90

 

예외처리에도 비용이 있다. [이 문제]를 풀다가 처음 발견했다.  

더 자세한 내용은 [Exceptions are slow in Java] 라는 포스팅을 읽고 알게되었다.

 

1. Filling in the stack trace is slow

한 예외마다 대략 1~5ms정도의 시간이 걸린다. 이 대부분의 시간은 exception thread stack을 채우는 데 걸리는 시간이다. stack trace가 깊을 수록, 더 오랜 시간이 걸린다.

대부분의 경우 예상할 수 없는 문제에 exception을 던지기 때문에 생성될 exception이 얼마나 많은 시간이 걸릴 지 알 수 없는 것도 문제다. 

 

2. How to avoid the stack trac penalty?

Using non-exceptional method results

String에서 int로 변환할 때처럼 예상가능한 exception이 있다면 그 exeption(NumberFormatException) 을 던지지 말고 대신 null을 리턴하는 방식이 좋다.

Caching an exception

stack trace가 정확하지 않아도 된다면, static final로 예외를 저장해두고 쓸 수도 있다. 자주쓰이는 라이브러리의 메서드거나 엄청나게 많이 변경하지 않아도 되는 경우에 이 방법을 활용하면 좋다.

Overriding `fillInStackTrace` method

stack trace를 채우는 것에 많은 시간을 보내므로 Throwable의 fillInStackStrace 오버라이딩을 통해 그 과정을 없앨 수 있다.

실험결과

원 포스팅의 실험결과다. 

Benchmark                                      Mode   Samples         Mean   Mean error    Units
t.ExceptionTests.createNewNoFillStackTrace    thrpt        10       12.328        0.061   ops/us
t.ExceptionTests.createNewNormalException     thrpt        10        0.236        0.005   ops/us
t.ExceptionTests.createNewStringHolder        thrpt        10       81.314        0.198   ops/us
t.ExceptionTests.throwCached                  thrpt        10      387.808        3.535   ops/us
t.ExceptionTests.throwNew                     thrpt        10        0.239        0.005   ops/us
t.ExceptionTests.throwNewNoFillStackTrace     thrpt        10       12.165        0.066   ops/us

캐싱이 가장 빠르고, 그 다음이 새로운 객체를 생성하는 일, fillstacktrace 오버라이딩이 세번째, 마지막이 기본적인 exception이다. 

 

결론

예외는 코드를 간단하게 만들어 가독성이 좋아진다. 하지만 무분별한 남용은 지양해야한다. 예외를 만들어내는 cost가 크기 때문이다. 특히 코딩테스트처럼 성능이 아주 중요한 이슈가 되는 작업이라면 신중하게 써야한다. 

 

댓글