matklad, 마이크로 벤치마크는 약 300ms로 맞추라고 권고
- matklad는 마이크로 벤치마크 입력 크기를 조정해 실행 시간이 약 300ms가 되도록 맞추라고 권고함. 밀리초는 1에서 999까지의 정수라 정밀도와 가독성을 함께 얻고, 10ms보다 빠르면 인터프리터 시작 같은 고정 비용에 결과가 휘둘리며, 1초를 넘기면 벤치마크를 10번 돌려 분산을 눈으로 확인하는 반복이 느려짐.
- 벤치마킹의 목적을 정밀 측정이 아니라 올바른 결정을 내릴 만큼의 직관 확보로 규정함. 수백 ms는 사람이 체감하는 범위라 숫자 감각이 아니라 시간 감각으로 최적화 결과를 판단할 수 있고, 느리던 CLI 명령이 즉각적으로 바뀌는 걸 확인하는 재미도 있다고 씀.
- 댓글에서는 도메인별 반론이 나옴. Java는 JIT 워밍업이 필요하고, 게임 렌더링은 300ms 표본으로 25분 뒤 프레임 드롭을 알 수 없으며, 데이터베이스는 대표 데이터셋 준비와 평가 자체에 오랜 시간이 걸림.
- 고처리량 시스템에서는 10ms도 과한 값이라는 지적이 나옴. 서버 측 지연이 1ms 미만, 클라이언트가 3-5ms 수준인 경우가 있고 평균은 의미가 없어 부하 상태의 p95, p99, p99.9를 봐야 함.
- 브라우저용 WebGPU 마이크로벤치마크를 만든 사람은 최신 브라우저가 기본으로 1ms 단위로 반올림하기 때문에 10ms 이상, 보통 50-100ms를 목표로 잡는다고 밝힘. CPU 클럭 조정과 인터럽트 때문에 재현이 안 돼 하이퍼스레딩과 부스트를 꺼도 해결되지 않았다는 AMD Zen 3 경험담도 나옴.
Hacker News opinions
벤치마크가 뭘 재는지에 따라 완전히 달라짐. criterion은 측정 안정화에 시간을 꽤 쓰는데, 그 정확도 필요 없다고 잘라버리면 노이즈 때문에 개선이라고 착각하고 헛수고한 경우를 많이 봤음. Java면 JIT가 충분히 최적화했는지도 봐야 하고.
도메인과 시간 스케일이 정말 중요함. 나노초가 중요한 시스템에서는 시간에 엄청 신경 썼지만 대체로는 OP 말에 동의함. 보통 신경 쓰는 건 밀리초 단위니까.
Python만 해본 것 같다는 건 좀 아닌 게, rust-analyzer랑 tigerbeetle 만든 사람임.
고볼륨 시스템에서 10ms는 좀 심함. 서버 쪽은 비즈니스 로직이나 캐시 히트면 1ms 아래고 클라이언트도 3-5ms 정도였음. Java였고. 집계 방식도 조심해야 함. 평균은 거의 항상 아무것도 안 알려주고, 부하 상태의 p95, p99, p99.9가 평균이나 중간값과 전혀 다른 그림을 보여줄 때가 많음.
hoisting 같은 최적화는 벤치마크가 결론 안 나도 가독성을 올려줌. 프로파일러가 중복 함수 호출이 실행 시간의 5%라고 해서 지웠더니 20% 빨라진 적도 있음. 프로파일러는 거짓말을 하고, 최적화는 여전히 흑마법임.
대표성 있는 입력으로 수백 ms를 채우기 어려운 벤치마크도 있음. 왜 1-10ms짜리 입력을 루프로 돌려서 분산과 시작 비용을 처리하지 않는지 궁금함. Rust 마이크로벤치 하네스는 몇 년 전부터 이걸 기본으로 해줬음.
웹이나 API 요청을 전제로 한 얘기로 읽힘. GPU나 CPU를 꽉 채우는 작업 벤치마크에는 밀리초가 너무 큰 단위임.
CPU 클럭이 계속 바뀌고 인터럽트랑 SMI 때문에 이런 벤치마크는 자주 깨짐. 하이퍼스레딩 끄고 scaling governor랑 부스트 만지고 클럭 고정해봤는데 지터가 너무 커서 재현이 안 돼서 포기했음. AMD Zen 3였음.
2008년쯤 HFT에서 10마이크로초 단위 연산을 벤치마크했는데 결과가 아주 예측 가능했음. C++이라 GC가 없고, 시작할 때 객체 풀을 미리 잡아 힙 경합을 피하고, I/O는 뮤텍스 걸린 연결 리스트로 다른 스레드에 넘기고, 처리 스레드를 전용 코어에 묶었음.
xkcd 2400 기준으로 읽어야 함. 최적화 안 된 코드에서 3배 10배 먹이를 찾을 때는 이 조언이 괜찮지만, 더 짜내야 하는 단계로 가면 못 믿을 규칙이 됨.
2% 미만 개선을 자랑한 프로젝트는 crate랑 v8 포인터 압축한 사람 둘밖에 못 봤음. 보통은 15%처럼 묶어서 보고하거나 TTFB 600ms에서 590ms처럼 밀리초로 보고함. 어떤 프로젝트에서는 2년 동안 매 마일스톤마다 30% 개선을 냈음.
WebGPU 마이크로벤치마크를 만들면서 알게 된 건데, 통제 못 하는 브라우저에서 돌리면 최신 브라우저가 기본으로 1ms 단위로 반올림해서 10ms 이상은 돌려야 정확한 결과가 나옴. 그래서 브라우저 벤치는 50-100ms를 목표로 잡음.
스레드 간 통신을 다룰 때는 마이크로초가 훨씬 편함. SQLite나 AspNetCore 볼 때도 마이크로초를 선호함.
내 xc 컴파일러 벤치마크는 롱폴 기준 1초에서 몇 초 단위임. arm64에서 SME/SME2 타깃으로 clang이나 g++보다 150배 빠른 결과가 나오면 비교 가능한 숫자를 얻으려고 더 오래 돌려야 할 때도 있음.