집계 배치가 메모리를 많이 써서 한도에 가까웠다. 코드에 재귀 호출이 있어서 그것 때문이라고 생각했다.
Table of contents
Open Table of contents
스위치로 기여를 분리했다
고치기 전에 그 부분의 기여만 따로 재기로 했고 마침 재귀를 켜고 끄는 인자가 있었다. 켠 것과 끈 것의 최대 사용량을 각각 쟀다.
차이는 백몇십 메가였고 전체 사용량에 비하면 작은 몫이었다. 추측한 원인이 실제로 얼마를 차지하는지는 그것만 빼고 한 번 돌려 보면 바로 나온다.
기저와 집계 본체
그러면 나머지가 어디서 오는지가 남는다. 입력을 로드한 직후의 사용량을 재 보니 시작하기도 전에 1기가에 가까웠다.
거기에 집계 본체가 대부분을 더하고 있었다. 최적화 대상이 재귀가 아니라 집계 본체라는 것이 이 분해로 확정됐다.
입력 로드가 남기는 것
입력 데이터 자체는 백몇십 메가였는데 로드 직후가 1기가였다. 나머지는 파싱하면서 문자열을 만들고 버리는 과정의 할당자 잔류였다.
실제로 안 쓰는데 운영체제에 돌려주지 않는 몫이라 코드를 줄여도 안 없어진다. 파싱 방식을 바꾸거나 스트리밍으로 읽어야 줄어드는 종류였다.
계측 도구가 보는 범위
쓴 도구는 언어 할당자를 통과한 것만 본다. 수치 배열처럼 다른 경로로 잡히는 것은 안 나온다.
그래서 프로세스 전체 사용량과 도구가 보고한 값의 차이가 그 몫이 된다. 이 데이터는 대부분 문자열이라 잘 잡혔지만 수치 위주였으면 도구만 보고 판단했을 때 크게 틀렸을 것이다.
최대치와 증분이 답하는 질문
이 도구에는 두 시점을 비교하는 기능이 있어서 먼저 그것을 썼는데 증가분이 아주 작게 나왔다. 그 기능은 반환 뒤에도 살아남은 것만 보여 주므로 중간에 썼다가 해제한 것은 안 나온다.
한도를 볼 때는 최대치를 봐야 하고 누수를 찾을 때는 증분을 본다. 둘 다 유효한 지표인데 답하는 질문이 다르므로 무엇을 알고 싶은지에 따라 골라야 한다.
이 측정으로 아무리 줄여도 남는 하한이 있다는 것도 드러났다. 집계 코드를 최적화해도 입력 잔류가 그대로면 전체가 그만큼 아래로는 안 내려간다.
정리
- 원인을 추측하지 말고 스위치로 기여분을 분리해 잰다
- 그것만 빼고 돌려 보면 실제 몫이 바로 나온다
- 입력 로드만으로 큰 기저가 생긴다
- 할당자 잔류는 코드를 줄여도 안 없어진다
- 계측 도구가 무엇을 보는지 알고 쓴다
- 도구가 안 잡는 영역은 프로세스 전체 값과의 차이로 본다
- 최대치와 증분은 다른 질문의 답이다
- 하한 구조를 알아야 줄였는데 왜 그대로냐에 답할 수 있다