Goのio.Readerの効率性:間接参照と型アサーションとの戦い

2025-05-19

Goの多くの関数はio.Readerインターフェースを入力として受け取ります。これにより、ストリーミングが可能になり、すべてをメモリにロードする必要がなくなります。しかし、既にバイトデータを持っている場合、それらを直接使用した方が効率的です。この記事では、著者がlibavifとlibheifを使用して画像をデコードした際の経験について説明しています。簡潔にするため、単純なメモリインターフェースを使用しましたが、Goのimage.Decode関数はio.ReaderでPeek関数の有無をチェックし、見つからない場合はbufio.Readerでラップするため、bytes.Readerのバイトを直接使用することができません。著者は型アサーションとunsafe.Pointerを使用してbufio.Readerとbytes.Readerを回避し、ゼロコピーを実現しています。しかし、この記事では、Goの型チェックとインターフェース設計における問題点、および結果として生じる「シャドーAPI」についても指摘しています。

開発