Benchmark in Milliseconds
벤치마크는 밀리초 단위로
마이크로벤치마크 입력 크기를 조절해 실행 시간을 약 300ms로 맞추자는 제안입니다. 고정 비용의 영향을 줄이면서도 반복 측정과 사람의 체감 비교를 빠르게 할 수 있지만, 정확한 통계나 특정 환경의 성능 검증이 필요한 작업에는 별도 접근이 필요합니다.
- 주제
AI 요약
마이크로벤치마크는 얼마나 오래 실행해야 할까요? 글쓴이는 입력 크기를 조절해 한 번 실행하는 데 약 300ms가 걸리도록 맞추는 방법을 권합니다. 정밀한 성능 수치 자체보다 최적화 결정을 내릴 만큼의 감각을 얻는 일이 벤치마크의 목적이라는 전제입니다.
300ms를 기준으로 삼는 이유
밀리초 단위 측정값은 1부터 999까지 정수로 읽힙니다. 1.31초와 239ms를 비교할 때처럼 단위를 바꾸거나 소수점을 살필 필요가 없고, 작은 개선도 눈에 들어옵니다. 10ms보다 짧은 실행은 인터프리터 시작 같은 고정 비용에 영향을 받기 쉽습니다. 수백 밀리초면 이런 일회성 비용을 줄이면서도 별도의 보정 기법에 기대지 않아도 된다는 설명입니다.
사람이 체감하기에도 수백 밀리초는 짧지만 알아차릴 수 있는 시간입니다. 숫자만 보지 않고 최적화 전후 속도를 직접 가늠할 수 있습니다. 반대로 1초를 넘기면 벤치마크를 여러 번 실행하며 반복 개선하기에 시간이 많이 듭니다. 실행을 열 번 반복해 변동 폭을 눈으로 확인하는 일도 빨라야 한다고 글쓴이는 말합니다.
적용 범위와 측정의 한계
댓글에서는 300ms라는 기준이 모든 벤치마크에 맞지는 않는다는 지적이 나옵니다. Java는 JIT 최적화가 충분히 이뤄지도록 워밍업해야 하고, 데이터베이스처럼 대표 입력을 준비하거나 실제 부하에서 성능을 확인하는 데 시간이 걸리는 분야도 있습니다. 게임 렌더링처럼 오랜 시간 뒤 발생하는 프레임 저하나 메모리 누수는 짧은 측정으로 드러나지 않을 수 있습니다.
측정 오차를 다루는 방법도 쟁점입니다. 한 댓글은 대조군과 여러 차례 번갈아 측정하고, 평균만 보지 말고 신뢰구간을 계산하자고 제안합니다. 반면 다른 댓글들은 분포가 비대칭이거나 꼬리가 긴 경우 평균과 신뢰구간만으로 실제 사용자 경험을 설명하기 어렵다고 지적합니다. 실행 시간의 백분위수나 통계 검정을 활용하자는 의견도 나옵니다.
도구를 쓰라는 조언도 있습니다. Java Microbenchmark Harness(JMH)는 워밍업, JVM 실행 간 변동 통제, 죽은 코드 제거 방지 기능을 제공한다는 댓글이 있습니다. 브라우저 벤치마크는 타이머 정밀도가 1ms 단위로 제한되는 경우가 있어 50~100ms 실행을 목표로 한다는 경험담도 공유됐습니다. 입력을 반복하는 방식은 시작 비용을 줄일 수 있지만, 작은 버퍼를 재사용하면 핫 캐시 성능만 측정할 수 있다는 주의도 나옵니다.
Hacker News 반응
- @vlovich123 — 무엇을 측정하는지, 얼마나 신뢰도 높은 결과를 원하는지, 어떤 분야인지에 따라 다릅니다. Criterion은 측정을 안정화해야 해서 시간이 꽤 걸리기도 합니다. 글쓴이는 그 정도 정확도가 필요 없다고 하지만, 저는 잡음을 개선으로 착각해 시간만 낭비하거나 실제로는 중립적이거나 성능을 떨어뜨린 변경을 개선이라고 주장하는 경우를 봤습니다. 10ms보다 짧으면 고정 비용이 결과를 왜곡한다는 말은 경험이 Python에만 국한된 것처럼 들립니다. Java는 JIT가 충분히 최적화하도록 해야 합니다. 데이터베이스처럼 대표 데이터를 만들고 성능을 평가하는 데 시간이 많이 드는 분야도 있습니다. 짧은 마이크로벤치마크는 출발점으로 유용하지만, 결국 전체 시스템의 정상 상태 성능도 봐야 합니다.
- @thadt — 분야와 시간 규모가 중요하다는 데 동의합니다. 나노초가 중요했던 시스템에서는 측정에 상당한 주의를 기울였습니다. 그래도 일반적으로는 원글 작성자 의견에 동의합니다. 저는 대부분 밀리초 단위에 관심이 있습니다. 작성자 경험이 Python에만 국한된 것 같다는 말은 아닙니다. rust-analyzer와 TigerBeetle을 보세요.
- @winwang — 좋은 생각입니다. 다만 수백 밀리초 동안 실행되는 대표 입력을 만들기 어려운 벤치마크도 있습니다. 1~10ms 입력을 반복해 변동과 시작 비용을 처리하지 않는 이유가 궁금합니다. Rust 마이크로벤치마크 도구는 몇 년 전부터 이런 작업을 기본으로 잘 처리했습니다.
- @nulltrace — 반복 실행은 괜찮지만, 같은 작은 버퍼를 재사용하면 대부분 핫 캐시 성능을 측정하게 됩니다.
- @spankalee — “신뢰구간을 두고 비교하라”고 말하는 편이 낫습니다. 절대 수치만으로는 판단하기 어렵습니다. CPU 부하, 스로틀링, GC 같은 변수가 있으니 같은 실행 안에서 대조군과 비교하고, 여러 번 번갈아 측정해 잡음이 공평하게 반영되도록 해야 합니다. 측정값 분포를 만든 뒤 평균만 비교하지 말고 95% 신뢰구간 같은 값을 계산해야 합니다. 신뢰구간이 겹치면 어느 쪽이 빠른지 모를 수 있습니다. 겹치지 않으면 어느 쪽이 빠른지 알 가능성이 큽니다.
- @bhouston — WebGPU 마이크로벤치마크를 만들면서, 통제할 수 없는 브라우저에서 실행할 때는 정확한 결과를 얻으려면 10ms보다 오래 실행해야 한다는 점을 알았습니다. 최신 브라우저는 기본적으로 시간을 가장 가까운 1ms 단위로 반올림합니다. 그래서 브라우저 벤치마크는 보통 50~100ms 실행을 목표로 합니다.
- @cchianel — Java를 벤치마크한다면 Java Microbenchmark Harness(JMH)가 있습니다. 워밍업을 여러 차례 진행해 인터프리터 코드가 아닌 JIT 최적화 코드를 측정합니다. JVM을 여러 번 새로 띄워 실행 간 변동을 줄이고,
Blackhole로 죽은 코드 제거를 막거나State로 설정 작업과 상수 접기를 제어하는 도구도 제공합니다. - @vardump — 연속적인 CPU 코어 클럭 변화, 시스템 인터럽트, SMI 때문에 이런 벤치마크는 자주 망가집니다. 하이퍼스레딩을 끄고, 스케일링 거버너와 부스트를 조정하고, CPU 주파수도 고정해 봤지만 결과가 재현되지 않을 만큼 흔들렸습니다. AMD Zen 3에서 겪은 일이지만 환경에 따라 다를 수 있습니다.
- @marginalia_nu — 시스템을 최대한 예측 가능하게 만드는 것과 별개로, 데이터가 시끄럽다는 점을 받아들이고 여러 번 측정한 뒤 통계 분석으로 대응해야 합니다. 원하는 신뢰도를 기준으로 워밍업 횟수, 측정 횟수, 벤치마크 시간을 정할 수 있습니다. 분포가 여러 봉우리를 보이면 백분위수 추적도 유용합니다.
- @1a527dd5 — 직접 기준을 만들지 말고 검증된 도구를 쓰세요. .NET이라면 BenchmarkDotNet을 예로 들 수 있습니다.
원문: matklad.github.io / 번역·요약: Trawling