Go's io.Reader Efficiency: A Battle with Indirection and Type Assertions

2025-05-19

Many Go functions take an io.Reader, enabling streaming and avoiding loading everything into memory. However, when you already have the bytes, using them directly is more efficient. This article describes the author's experience decoding images with libavif and libheif. For simplicity, the simple memory interfaces were used, but the Go image.Decode function checks for a Peek function on the io.Reader, wrapping with bufio.Reader if not found, preventing direct use of bytes.Reader. The author cleverly uses type assertions and unsafe.Pointer to bypass bufio.Reader and bytes.Reader, achieving zero-copy. However, the article highlights issues in Go's type checking and interface design, including the resulting 'shadow APIs'.

Development