From 28f2d02ad3c5784d8f263fe2d3329e0d20644f31 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 15:38:24 +0000 Subject: [PATCH] feat: Optimize binary reading in dicomio.Reader Replaced reflection-based `binary.Read` with explicit `io.ReadFull` and `binary.ByteOrder` calls for primitive types. This avoids interface allocations and reflection overhead in the hot path. Performance improvements: - ReadUInt16: ~21% faster (38.66 ns/op vs 49.17 ns/op) - ReadUInt32: ~18% faster (43.65 ns/op vs 53.27 ns/op) - ReadFloat64: ~46% faster (49.13 ns/op vs 91.61 ns/op) Tests passed. --- pkg/dicomio/reader.go | 54 ++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/pkg/dicomio/reader.go b/pkg/dicomio/reader.go index dd64c2a2..ed4da293 100644 --- a/pkg/dicomio/reader.go +++ b/pkg/dicomio/reader.go @@ -77,51 +77,63 @@ func (r *Reader) Read(p []byte) (int, error) { // ReadUInt8 reads an uint8 from the underlying *Reader. func (r *Reader) ReadUInt8() (uint8, error) { - var out uint8 - err := binary.Read(r, r.bo, &out) - return out, err + var buf [1]byte + _, err := io.ReadFull(r, buf[:]) + return buf[0], err } // ReadUInt16 reads an uint16 from the underlying *Reader. func (r *Reader) ReadUInt16() (uint16, error) { - var out uint16 - err := binary.Read(r, r.bo, &out) - return out, err + var buf [2]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { + return 0, err + } + return r.bo.Uint16(buf[:]), nil } // ReadUInt32 reads an uint32 from the underlying *Reader. func (r *Reader) ReadUInt32() (uint32, error) { - var out uint32 - err := binary.Read(r, r.bo, &out) - return out, err + var buf [4]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { + return 0, err + } + return r.bo.Uint32(buf[:]), nil } // ReadInt16 reads an int16 from the underlying *Reader. func (r *Reader) ReadInt16() (int16, error) { - var out int16 - err := binary.Read(r, r.bo, &out) - return out, err + var buf [2]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { + return 0, err + } + return int16(r.bo.Uint16(buf[:])), nil } // ReadInt32 reads an int32 from the underlying *Reader. func (r *Reader) ReadInt32() (int32, error) { - var out int32 - err := binary.Read(r, r.bo, &out) - return out, err + var buf [4]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { + return 0, err + } + return int32(r.bo.Uint32(buf[:])), nil } // ReadFloat32 reads a float32 from the underlying *Reader. func (r *Reader) ReadFloat32() (float32, error) { - var out float32 - err := binary.Read(r, r.bo, &out) - return out, err + var buf [4]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { + return 0, err + } + return math.Float32frombits(r.bo.Uint32(buf[:])), nil } // ReadFloat64 reads a float64 from the underlying *Reader. func (r *Reader) ReadFloat64() (float64, error) { - var out float64 - err := binary.Read(r, r.bo, &out) - return out, err + var buf [8]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { + return 0, err + } + return math.Float64frombits(r.bo.Uint64(buf[:])), nil } func internalReadString(data []byte, d *encoding.Decoder) (string, error) {