제목이 마치 Rust가 5배 성능 향상을 준 것처럼 보이지만, 실제로는 느려졌다는 점이 아이러니함
문제는 Rust로 작성된 소프트웨어가 C로 된 libpg_query를 써야 했는데, 직접 연결할 수 없어 Protobuf 기반의 Rust–C 바인딩을 사용한 것임
이 방식이 느려서, 결국 LLM의 도움으로 비이식성이지만 훨씬 최적화된 바인딩을 새로 작성했음
만약 애초에 C로 썼다면 변환 과정이 필요 없었을 것임. 즉, 제목은 “Rust 사용으로 인한 성능 손실을 줄였다”가 더 정확했을 것임
변환 계층은 이식성과 보안을 주지만, 결국 복사·변환·직렬화가 반복되며 앱을 느리게 만드는 원인 중 하나라고 생각함
Rust가 느린 게 아니라, 외부 라이브러리의 비효율적 설계가 문제였음
Rust에서 C 라이브러리를 호출하는 건 매우 쉽고, 안전한 래퍼도 이미 많이 존재함
Protobuf를 중간에 둔 구조는 거의 본 적이 없으며, 그게 병목이었음
제목은 단순히 클릭을 유도하기 위한 “Rust로 다시 썼다”식 밈에 가깝다고 봄
C로 썼다면 더 빠를 거라는 건 공정하지 않음
원래 라이브러리가 직렬화/역직렬화를 반복하는 잘못된 설계를 하고 있었고, 그걸 제거한 게 핵심임
제목은 “Protobuf를 일반 API로 교체해 5배 빨라졌다”가 더 정확함
왜 바로 FFI를 쓰지 않았는지 궁금함
Rust에서 C 바인딩은 가장 쉽고, 큰 API가 아니라면 단순함
Protobuf는 메모리 내 데이터 교환에는 부적절한 도구라고 생각함
LLM으로 최적화를 했다면, 차라리 C 라이브러리를 Rust로 완전히 포팅하는 데 썼으면 어땠을까 생각함
앞으로 LLM 덕분에 다양한 언어로의 포팅이 폭발적으로 늘어날 것 같음
Rust와 Postgres 사이에 Protobuf를 둔 건 성능 악몽 수준임. 그런 라이브러리가 인기를 얻은 게 놀라움
제목이 다소 오해를 부름
사실상 “Protobuf 직렬화 단계를 제거했더니 빨라졌다”는 내용임
Protobuf는 단순 복사로는 불가능한 버전 호환성을 제공함
클라이언트와 서버가 독립적으로 업데이트돼도 동작하게 해주며, 여러 언어 간 통신을 쉽게 함
대규모 시스템에서는 이런 유연성이 매우 중요함
Protobuf 직렬화가 단순 메모리 복사보다 5배 느리다는 건 오히려 생각보다 빠르다는 인상임
memcpy나 mmap이 훨씬 빠르지만, Rust 진영에서는 그런 비안전한 방식을 꺼림
이런 경우엔 Arrow 같은 표준화된 zero-copy 포맷을 쓰면 좋을 것 같음. 언어별 패딩 문제나 보안 검사를 자동으로 처리해줌
Rust 때문이 아니라, Protobuf를 일반화된 저장 포맷으로 쓴 게 느린 원인일 수 있음
결국 특정 목적에 맞게 단순화한 게 핵심임
“Protobuf를 네이티브 최적화 구현으로 교체했다”는 제목은 주목을 덜 받았을 것임
Rust를 제목에 넣은 건 클릭 유도를 위한 선택 같음
기사 제목이 논란을 부르지만, 본문은 그걸 인식하고 있음
실제로는 Rust와 거의 관계가 없지만, Rust가 없었다면 메인 페이지에 오르지 못했을 것임
pg_query의 원 저자가 배경을 설명함
원래 pganalyze에서 Postgres 쿼리를 파싱해 테이블 참조를 찾고, 쿼리를 재작성·포맷하는 용도로 사용했음
초기엔 JSON을 썼지만, 이후 Protobuf로 전환해 여러 언어(Ruby, Go, Rust, Python 등)에서 타입 안정성 있는 바인딩을 쉽게 제공하기 위함이었음
Rust 같은 언어는 FFI가 낫지만, 다른 언어들은 유지보수 부담이 큼
Lev의 시도는 지지하며, 앞으로 libpg_query에 직접 FFI로 접근할 수 있는 함수를 추가할 예정임
다만 성능이 중요하지 않은 경우엔 Protobuf가 여전히 더 편리한 선택임
“5배 빠르다”는 말이 Cap’n Proto의 “무한히 빠르다”는 농담을 떠올리게 함
Cap’n Proto는 Protobuf 제작자가 만든 것으로, 파싱이 필요 없는 구조라서 그런 표현을 쓴 것임
하지만 실제로 써보면 Cap’n Proto는 사용성이 떨어짐
제목은 과장됐지만, 실제 작업은 인상적임
Protobuf를 완전히 없앤 게 아니라 사용 방식을 최적화한 것임
“X로 바꿨더니 5배 빨라졌다”는 문구는 대개 “엉망이던 구현을 고쳤다”는 뜻임
핵심 교훈은
직렬화/역직렬화는 숨은 병목이 되기 쉬움
기본 구현은 대부분 특정 상황에 최적화돼 있지 않음
프로파일링을 통해 병목을 정확히 찾아야 함
Rust FFI에도 오버헤드가 있으므로, 진짜 성과는 언어가 아니라 데이터 흐름 재설계와 최적화 노력 덕분임
FlatBuffers가 더 빠르지만, Protobuf를 쓰는 이유는 대기업이 유지보수하기 때문임
하지만 FlatBuffers도 Google이 유지보수함
결국 “Google이 만든 것이라 안전하다”는 인식이 근거 없음
나도 예전에 Google 플랫폼(code.google.com)에 코드를 올렸다가 망한 경험이 있음
단순히 메모리 공유와 버전 필드만 있는 zero-copy 구조면 충분한데, 굳이 Protobuf를 쓸 이유가 없다고 생각함
Google은 아직도 문자열 필드 zero-copy 최적화를 공개하지 않았음
Protobuf 성능은 농담 수준이라 생각함
직렬화가 사실상 무료인 zero-copy 포맷을 써야 함
예를 들어 내가 만든 Lite³는 FlatBuffers보다 242배 빠름
하지만 그 라이브러리는 2025년 11월 이후에야 등장했음
Protobuf를 쓰는 이유는 생태계, 스키마, 언어별 툴링 등 수많은 현실적 이유 때문임
실제로는 Rust나 Protobuf 문제가 아니라, PostgreSQL 추상화 계층의 비효율적 직렬화 구현이 원인이었음
pgdog는 그 계층을 제거하고 C API로 직접 데이터를 전달했음
필요 없는 기능을 제거하면 당연히 빨라짐
하지만 어떤 사람들에게는 여전히 직렬화가 필요한 상황이 있음
그런 이들에게 “Rust로 바꾸라”는 제목은 잘못된 메시지임
결국 대부분의 경우엔 JSON이면 충분하고, 정말로 더 빠른 게 필요하다면 직렬화 자체를 피해야 함
이건 불공정한 비교임
IPC 통신에 직렬화 프로토콜을 쓰는 건 당연히 오버헤드가 있음
“20% 빨라지면 개선, 10배 빨라지면 처음부터 잘못 만든 것”이라는 말이 딱 들어맞는 사례임
Hacker News 의견들
제목이 마치 Rust가 5배 성능 향상을 준 것처럼 보이지만, 실제로는 느려졌다는 점이 아이러니함
문제는 Rust로 작성된 소프트웨어가 C로 된 libpg_query를 써야 했는데, 직접 연결할 수 없어 Protobuf 기반의 Rust–C 바인딩을 사용한 것임
이 방식이 느려서, 결국 LLM의 도움으로 비이식성이지만 훨씬 최적화된 바인딩을 새로 작성했음
만약 애초에 C로 썼다면 변환 과정이 필요 없었을 것임. 즉, 제목은 “Rust 사용으로 인한 성능 손실을 줄였다”가 더 정확했을 것임
변환 계층은 이식성과 보안을 주지만, 결국 복사·변환·직렬화가 반복되며 앱을 느리게 만드는 원인 중 하나라고 생각함
Rust에서 C 라이브러리를 호출하는 건 매우 쉽고, 안전한 래퍼도 이미 많이 존재함
Protobuf를 중간에 둔 구조는 거의 본 적이 없으며, 그게 병목이었음
제목은 단순히 클릭을 유도하기 위한 “Rust로 다시 썼다”식 밈에 가깝다고 봄
원래 라이브러리가 직렬화/역직렬화를 반복하는 잘못된 설계를 하고 있었고, 그걸 제거한 게 핵심임
제목은 “Protobuf를 일반 API로 교체해 5배 빨라졌다”가 더 정확함
Rust에서 C 바인딩은 가장 쉽고, 큰 API가 아니라면 단순함
Protobuf는 메모리 내 데이터 교환에는 부적절한 도구라고 생각함
앞으로 LLM 덕분에 다양한 언어로의 포팅이 폭발적으로 늘어날 것 같음
제목이 다소 오해를 부름
사실상 “Protobuf 직렬화 단계를 제거했더니 빨라졌다”는 내용임
클라이언트와 서버가 독립적으로 업데이트돼도 동작하게 해주며, 여러 언어 간 통신을 쉽게 함
대규모 시스템에서는 이런 유연성이 매우 중요함
Rust 때문이 아니라, Protobuf를 일반화된 저장 포맷으로 쓴 게 느린 원인일 수 있음
결국 특정 목적에 맞게 단순화한 게 핵심임
Rust를 제목에 넣은 건 클릭 유도를 위한 선택 같음
pg_query의 원 저자가 배경을 설명함
원래 pganalyze에서 Postgres 쿼리를 파싱해 테이블 참조를 찾고, 쿼리를 재작성·포맷하는 용도로 사용했음
초기엔 JSON을 썼지만, 이후 Protobuf로 전환해 여러 언어(Ruby, Go, Rust, Python 등)에서 타입 안정성 있는 바인딩을 쉽게 제공하기 위함이었음
Rust 같은 언어는 FFI가 낫지만, 다른 언어들은 유지보수 부담이 큼
Lev의 시도는 지지하며, 앞으로 libpg_query에 직접 FFI로 접근할 수 있는 함수를 추가할 예정임
다만 성능이 중요하지 않은 경우엔 Protobuf가 여전히 더 편리한 선택임
“5배 빠르다”는 말이 Cap’n Proto의 “무한히 빠르다”는 농담을 떠올리게 함
제목은 과장됐지만, 실제 작업은 인상적임
Protobuf를 완전히 없앤 게 아니라 사용 방식을 최적화한 것임
“X로 바꿨더니 5배 빨라졌다”는 문구는 대개 “엉망이던 구현을 고쳤다”는 뜻임
핵심 교훈은
Rust FFI에도 오버헤드가 있으므로, 진짜 성과는 언어가 아니라 데이터 흐름 재설계와 최적화 노력 덕분임
FlatBuffers가 더 빠르지만, Protobuf를 쓰는 이유는 대기업이 유지보수하기 때문임
결국 “Google이 만든 것이라 안전하다”는 인식이 근거 없음
단순히 메모리 공유와 버전 필드만 있는 zero-copy 구조면 충분한데, 굳이 Protobuf를 쓸 이유가 없다고 생각함
Protobuf 성능은 농담 수준이라 생각함
직렬화가 사실상 무료인 zero-copy 포맷을 써야 함
예를 들어 내가 만든 Lite³는 FlatBuffers보다 242배 빠름
Protobuf를 쓰는 이유는 생태계, 스키마, 언어별 툴링 등 수많은 현실적 이유 때문임
실제로는 Rust나 Protobuf 문제가 아니라, PostgreSQL 추상화 계층의 비효율적 직렬화 구현이 원인이었음
pgdog는 그 계층을 제거하고 C API로 직접 데이터를 전달했음
필요 없는 기능을 제거하면 당연히 빨라짐
하지만 어떤 사람들에게는 여전히 직렬화가 필요한 상황이 있음
그런 이들에게 “Rust로 바꾸라”는 제목은 잘못된 메시지임
결국 대부분의 경우엔 JSON이면 충분하고, 정말로 더 빠른 게 필요하다면 직렬화 자체를 피해야 함
이건 불공정한 비교임
IPC 통신에 직렬화 프로토콜을 쓰는 건 당연히 오버헤드가 있음
“20% 빨라지면 개선, 10배 빨라지면 처음부터 잘못 만든 것”이라는 말이 딱 들어맞는 사례임