Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

Commit 68dcd6c

Browse files
authored
cfitsio: optimize ImageHDU.load
- simplified the code by making use of the type switch - removed extra memory buffer allocation and copy - removed unused counting of 0 elements Benchmarks show that Read()/load() now runs ~16% faster
1 parent 8d74601 commit 68dcd6c

File tree

1 file changed

+8
-32
lines changed

1 file changed

+8
-32
lines changed

image.go

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ func (hdu *ImageHDU) Data(data interface{}) error {
6666

6767
// load loads the image data associated with this HDU into v.
6868
func (hdu *ImageHDU) load(v reflect.Value) error {
69-
var err error
7069
hdr := hdu.Header()
7170
naxes := len(hdr.Axes())
7271
if naxes == 0 {
@@ -76,78 +75,65 @@ func (hdu *ImageHDU) load(v reflect.Value) error {
7675
for _, dim := range hdr.Axes() {
7776
nelmts *= int(dim)
7877
}
79-
rv := reflect.MakeSlice(v.Type(), nelmts, nelmts)
78+
if v.Len() != nelmts {
79+
return fmt.Errorf("cfitsio: slice length [%v] is not as expected [%v]", v.Len(), nelmts)
80+
}
8081

8182
c_start := C.LONGLONG(0)
8283
c_nelmts := C.LONGLONG(nelmts)
83-
c_anynull := C.int(0)
8484
c_status := C.int(0)
8585
c_imgtype := C.int(0)
8686
var c_ptr unsafe.Pointer
87-
switch rv.Interface().(type) {
87+
switch data := v.Interface().(type) {
8888
case []byte:
8989
c_imgtype = C.TBYTE
90-
data := rv.Interface().([]byte)
9190
c_ptr = unsafe.Pointer(&data[0])
9291

9392
case []int8:
9493
c_imgtype = C.TBYTE
95-
data := rv.Interface().([]int8)
9694
c_ptr = unsafe.Pointer(&data[0])
9795

9896
case []int16:
9997
c_imgtype = C.TSHORT
100-
data := rv.Interface().([]int16)
10198
c_ptr = unsafe.Pointer(&data[0])
10299

103100
case []uint16:
104101
c_imgtype = C.TUSHORT
105-
data := rv.Interface().([]uint16)
106102
c_ptr = unsafe.Pointer(&data[0])
107103

108104
case []int32:
109105
c_imgtype = C.TINT
110-
data := rv.Interface().([]int32)
111106
c_ptr = unsafe.Pointer(&data[0])
112107

113108
case []uint32:
114109
c_imgtype = C.TUINT
115-
data := rv.Interface().([]uint32)
116110
c_ptr = unsafe.Pointer(&data[0])
117111

118112
case []int64:
119113
c_imgtype = C.TLONGLONG
120-
data := rv.Interface().([]int64)
121114
c_ptr = unsafe.Pointer(&data[0])
122115

123116
case []uint64:
124117
c_imgtype = C.TULONGLONG
125-
data := rv.Interface().([]uint64)
126118
c_ptr = unsafe.Pointer(&data[0])
127119

128120
case []float32:
129121
c_imgtype = C.TFLOAT
130-
data := rv.Interface().([]float32)
131122
c_ptr = unsafe.Pointer(&data[0])
132123

133124
case []float64:
134125
c_imgtype = C.TDOUBLE
135-
data := rv.Interface().([]float64)
136126
c_ptr = unsafe.Pointer(&data[0])
137127

138128
default:
139-
panic(fmt.Errorf("invalid image type [%T]", rv.Interface()))
129+
panic(fmt.Errorf("invalid image type [%T]", v.Interface()))
140130
}
141-
C.fits_read_img(hdu.f.c, c_imgtype, c_start+1, c_nelmts, c_ptr, c_ptr, &c_anynull, &c_status)
131+
C.fits_read_img(hdu.f.c, c_imgtype, c_start+1, c_nelmts, nil, c_ptr, nil, &c_status)
142132
if c_status > 0 {
143133
return to_err(c_status)
144134
}
145135

146-
n := reflect.Copy(v, rv)
147-
if n != nelmts {
148-
err = fmt.Errorf("cfitsio: copied [%v] elements. expected [%v]", n, nelmts)
149-
}
150-
return err
136+
return nil
151137
}
152138

153139
// Write writes the image to disk
@@ -175,55 +161,45 @@ func (hdu *ImageHDU) Write(data interface{}) error {
175161
c_imgtype := C.int(0)
176162
var c_ptr unsafe.Pointer
177163

178-
switch rv.Interface().(type) {
164+
switch data := rv.Interface().(type) {
179165
case []byte:
180166
c_imgtype = C.TBYTE
181-
data := rv.Interface().([]byte)
182167
c_ptr = unsafe.Pointer(&data[0])
183168

184169
case []int8:
185170
c_imgtype = C.TBYTE
186-
data := rv.Interface().([]int8)
187171
c_ptr = unsafe.Pointer(&data[0])
188172

189173
case []int16:
190174
c_imgtype = C.TSHORT
191-
data := rv.Interface().([]int16)
192175
c_ptr = unsafe.Pointer(&data[0])
193176

194177
case []uint16:
195178
c_imgtype = C.TUSHORT
196-
data := rv.Interface().([]uint16)
197179
c_ptr = unsafe.Pointer(&data[0])
198180

199181
case []int32:
200182
c_imgtype = C.TINT
201-
data := rv.Interface().([]int32)
202183
c_ptr = unsafe.Pointer(&data[0])
203184

204185
case []uint32:
205186
c_imgtype = C.TUINT
206-
data := rv.Interface().([]uint32)
207187
c_ptr = unsafe.Pointer(&data[0])
208188

209189
case []int64:
210190
c_imgtype = C.TLONGLONG
211-
data := rv.Interface().([]int64)
212191
c_ptr = unsafe.Pointer(&data[0])
213192

214193
case []uint64:
215194
c_imgtype = C.TULONGLONG
216-
data := rv.Interface().([]uint64)
217195
c_ptr = unsafe.Pointer(&data[0])
218196

219197
case []float32:
220198
c_imgtype = C.TFLOAT
221-
data := rv.Interface().([]float32)
222199
c_ptr = unsafe.Pointer(&data[0])
223200

224201
case []float64:
225202
c_imgtype = C.TDOUBLE
226-
data := rv.Interface().([]float64)
227203
c_ptr = unsafe.Pointer(&data[0])
228204

229205
default:

0 commit comments

Comments
 (0)