예외처리에도 비용이 있다. [이 문제]를 풀다가 처음 발견했다.
더 자세한 내용은 [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가 크기 때문이다. 특히 코딩테스트처럼 성능이 아주 중요한 이슈가 되는 작업이라면 신중하게 써야한다.
'기록 > JAVA' 카테고리의 다른 글
[JAVA] Queue 인터페이스 구현하기 (1) Queue (0) | 2023.07.10 |
---|---|
[JAVA] System.arraycopy, Array.clone() (0) | 2022.05.01 |
[JAVA] library, framework, pattern, architecture 차이 (0) | 2022.04.19 |
[JAVA] String.format 과정 (0) | 2022.04.08 |
[JAVA] 전위연산, 후위연산 메모리 및 속도 차이 (0) | 2022.03.14 |
댓글