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.

Reply via email to