Something like this is a bit simpler, avoids the need for unsafe, and may be a little faster too: https://play.golang.org/p/4jayHwLroR It may be quicker to use a type switch: https://play.golang.org/p/4uu2XeVM9m
It's a pity that about the need for a dynamic type conversion on every field, but the best I could come up with for avoiding it was this, which probably won't be any faster: https://play.golang.org/p/3Ihgdm1Yjo Or perhaps this (not recommended), which is horribly unsafe and again probably won't be any faster: https://play.golang.org/p/uLdi7Sw3Ml On 29 October 2017 at 23:20, DrGo <salah.mah...@gmail.com> wrote: > Thanks Michael, > Here is the cleaner current version, thanks to your suggestion: > > //writeData loops over the field vectors and write their binary > representation to an io.Writer > func (sf *File) writeData(w io.Writer) error { > if sf.NoObs == 0 { > return nil > } > if len(sf.fields) == 0 { > return fmt.Errorf("No fields") > } > bs := make([]byte, sf.recordSize) > for i := int32(0); i < sf.NoObs; i++ { > offset := 0 > for _, f := range sf.fields { > switch f.FieldType { > case StataByte: > v := f.data.([]int8)[i] > bs[offset] = byte(v) > offset++ > case StataInt: > v := f.data.([]int16)[i] > bs[offset] = byte(v) > offset++ //incrementing the offset instead of using > bs[offset+1] to avoid doing the addition twice > bs[offset] = byte(v >> 8) > offset++ > case StataLong: > v := f.data.([]int32)[i] > bs[offset] = byte(v) > offset++ > bs[offset] = byte(v >> 8) > offset++ > bs[offset] = byte(v >> 16) > offset++ > bs[offset] = byte(v >> 24) > offset++ > case StataFloat: > base := *(*[4]byte)(unsafe.Pointer(&f.data.([]float32)[i])) > copy(bs[offset:], base[:]) > offset += 4 > case StataDouble: > base := *(*[8]byte)(unsafe.Pointer(&f.data.([]float64)[i])) > copy(bs[offset:], base[:]) > offset += 8 > default: > return fmt.Errorf("Field type [%d] not supported in field > %s", f.FieldType, f.Name) > } > } > if _, err := w.Write(bs); err != nil { > return err > } > } > return nil > } > > > On Saturday, October 28, 2017 at 9:38:19 AM UTC-5, Michael Jones wrote: >> >> you could do your unsafe cast to an appropriately-sized byte array and >> write that as a single call or use it to access the bytes: >> >> base := *(*[8]byte)(unsafe.Pointer(&doubleThing)) >> bs[offset+0]=base[0] >> bs[offset+1]=base[1] >> : >> offset+=8 >> >> > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.