Web Streams API의 한계를 넘어선 새로운 스트림 API 제안
Web Streams API의 복잡성, 성능 문제, 그리고 락킹(Locking) 모델의 취약성을 지적하며 개선 필요성을 제기
Async Iterators를 활용한 새로운 스트림 API 설계를 통해 간결성, 성능, 그리고 명시적인 백프레셔(Backpressure) 제어 가능성을 강조
Sync/Async 분리를 통해 CPU 바운드(CPU-bound) 작업에서 불필요한 오버헤드를 제거하여 성능을 향상시킴
다양한 런타임 환경에서의 벤치마크 결과를 통해 기존 Web Streams API 대비 최대 120배의 성능 향상을 입증
Web Streams API의 근본적인 문제점
저자는 Web Streams API의 설계 결함으로 인해 과도한 복잡성, 성능 저하, 그리고 잦은 오류 발생을 지적한다. 특히, getReader()와 releaseLock()을 이용한 락킹(Locking) 모델은 스트림 사용의 어려움을 야기하며, BYOB(Bring Your Own Buffer)와 같은 기능은 오히려 복잡성만 더하고 실질적인 성능 향상에는 기여하지 못한다고 비판한다. 또한, 백프레셔(Backpressure) 메커니즘의 부실한 구현으로 인해 예상치 못한 메모리 사용량 증가를 초래할 수 있다고 지적한다.
Async Iterators 기반의 새로운 API 설계
저자는 async iterator를 활용한 새로운 스트림 API 설계를 제안하며, 간결하고 직관적인 사용성을 강조한다. 이 새로운 API는 스트림을 AsyncIterable로 취급하여 for await...of 구문을 통해 쉽게 데이터를 소비할 수 있도록 한다. 또한, pull-through 방식을 통해 불필요한 버퍼링을 줄이고, 명시적인 백프레셔(Backpressure) 제어를 통해 메모리 사용량을 효율적으로 관리할 수 있도록 설계되었다. 특히, Sync/Async 분리를 통해 CPU 바운드(CPU-bound) 작업의 성능을 극대화한다.
성능 향상을 위한 핵심 설계 원칙
새로운 API는 성능 향상을 위해 여러 가지 핵심 원칙을 따른다. 먼저, 스트림은 AsyncIterable이므로 별도의 reader/writer를 관리할 필요가 없다. 둘째, pull-through 방식을 통해 불필요한 작업을 방지한다. 셋째, 명시적인 백프레셔(Backpressure) 정책을 통해 메모리 사용량을 제어한다. 넷째, Batched Chunks를 사용하여 비동기 오버헤드를 줄인다. 마지막으로, sync/async 분리를 통해 CPU 바운드(CPU-bound) 작업의 성능을 극대화한다.
실제 벤치마크 결과 및 런타임별 최적화
저자는 새로운 API의 성능을 벤치마크를 통해 입증했으며, 기존 Web Streams API 대비 최대 120배의 성능 향상을 보였다고 주장한다. 특히, TransformStream 파이프라인에서 성능 향상이 두드러졌다. 또한, Node.js, Deno, Bun 등 다양한 런타임 환경에서 새로운 API를 구현하여 각 환경에 맞는 최적화를 수행할 수 있음을 보여주었다. Vercel의 Malte Ubl은 Node.js Web Streams 구현 개선 연구를 통해 Promise 오버헤드를 줄여 성능을 향상시켰다.