A slightly faster slimmer curl
조금 더 빠르고 작아진 curl
curl의 새 성능 테스트를 바탕으로 여러 내부 함수와 구조체를 개선했습니다. Base64 디코딩은 40%, URL 인코딩은 약 4배 빨라졌고, 전송에 쓰이는 구조체와 메모리 사용량도 줄었습니다. 일반적인 전송에서 사용자가 체감할 차이는 크지 않을 수 있다고 설명합니다.
- 주제
에디터 노트
함수별 속도 향상과 구조체 축소는 수치로 확인되지만, 저자도 대부분의 전송에서 사용자 체감이 크지 않다고 선을 긋습니다. 성능 테스트 결과는 내부 처리 개선을 보여주지만 실제 전송 시간 단축 폭까지 제시하지는 않습니다. 댓글의 메모리 아레나 제안은 할당 횟수를 더 줄이는 방향이지만, 이 글의 테스트에서는 이미 100회에서 96회로 감소했습니다. 아레나가 성능을 더 높일지는 제안자의 추정이며 측정 결과는 없습니다. 이번 변경은 확인 가능한 함수와 메모리 수치를 차근차근 개선한 사례로 읽을 수 있습니다.
AI 요약
curl 팀은 성능 테스트를 실행한 지 두 달 남짓한 시점에 초기 개선 결과를 공개했습니다. 성능 그래프와 테스트를 활용해 느린 부분을 찾아 손봤으며, 이번 변경 사항은 다음 날 출시 예정인 curl 8.23.0에 포함됩니다. 저자는 대부분의 전송에서 사용자가 차이를 뚜렷하게 느끼지는 못하겠지만, 필요 이상으로 느리게 동작하는 부분을 줄이는 작업이라고 설명합니다.
내부 처리 함수 개선
Base64 인코딩 함수는 여러 변경을 거쳐 두 배 넘게 빨라졌고 디코딩은 40% 빨라졌습니다. URL에서 안전하지 않은 바이트를 퍼센트 인코딩하는 함수는 약 네 배, 디코딩 함수는 두 배 넘게 빨라졌습니다. 쿠키 헤더 등에 쓰이는 날짜 문자열을 Unix epoch 초 단위 값으로 바꾸는 처리도 두 배 넘게 빨라졌습니다. 요일과 월 이름, 시간대 이름을 찾는 함수를 새로 작성한 점이 주된 이유입니다.
URL 파싱은 여러 URL을 대상으로 한 테스트에서 기존보다 20~30% 빨라졌습니다. URL을 구성 요소로 나누고 유효성을 검사하는 기능은 libcurl API에도 제공됩니다. 개선된 파서는 잘못된 URL에서 오류 원인을 더 정확히 돌려줍니다.
libcurl은 플랫폼마다 일관된 동작을 보장하려고 자체 printf() 구현을 사용합니다. 이 구현은 한 바이트씩 처리하는 대신 덩어리 단위로 처리하도록 바뀌어, 대부분의 호출이 5~15% 빨라졌습니다. 10진수, 16진수, 8진수 문자열을 정수로 바꾸는 내부 함수도 경계 검사를 대부분의 반복에서 피하는 방식으로 개선해 거의 두 배 빨라졌습니다. 이 함수는 64비트 값과 오버플로 검출, 최대값 제한을 지원합니다.
구조체와 메모리 사용량
easy handle 구조체는 두 달 전 4,256바이트에서 3,064바이트로 약 28% 줄었습니다. libcurl에서 동시에 진행하는 전송마다 하나씩 할당하는 구조체입니다. 전송 집합마다 할당하는 multi handle은 900바이트에서 656바이트로 약 27% 줄었고, 연결마다 할당하는 connectdata는 824바이트에서 656바이트로 20% 넘게 줄었습니다.
평문 HTTP로 512MB 파일 하나를 내려받는 테스트에서는 curl 도구가 사용하는 메모리 할당 횟수가 100회에서 96회로 줄었습니다. 최대 할당 메모리는 130,622바이트에서 126,875바이트로 감소했습니다. 이 수치에는 102,400바이트짜리 다운로드 버퍼가 포함됩니다. 버퍼를 제외하면 메모리 사용량은 15% 감소합니다. 저자는 이 사례에서 할당 횟수와 메모리를 더 줄이기가 쉽지 않다고 덧붙입니다.
성능 개선을 확인하는 방법
각 함수의 성능 테스트는 curl 저장소에 포함되어 있어 누구나 실행할 수 있습니다. 개선을 제안하는 사람이 같은 테스트로 결과를 확인할 수 있도록 했습니다.
Lobsters 반응
- @mariusor — 다음 단계로 호출자가 직접 할당 함수를 전달할 수 있게 하는 게 자연스러워 보입니다. 작은 할당을 여러 번 하는 대신 메모리 아레나처럼 큰 덩어리 하나를 할당하면, 100회에서 96회로 줄인 것과 같은 개선을 더 얻을 수 있을 것 같습니다.
원문: Daniel Stenberg 블로그 / 번역·요약: Trawling