I have this example in C
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main()
{
uint32_t dest[4];
uint8_t src[16] = {0x11, 0x12, 0x13, 0x14,
0x22, 0x22, 0x22, 0x22,
0x33, 0x33, 0x33, 0x33,
0x44, 0x44, 0x44, 0x44};
memcpy(dest, src, sizeof(src));
printf("X X X X\n", dest[0], dest[1], dest[2], dest[3]);
return 0;
}
and I'm migrating to golang, I don't want use C.memcpy and I'm searching for a fast alternative. This is my code
package main
import (
"fmt"
"encoding/binary"
)
func main() {
dest := make([]uint32, 16)
var src = []byte{0x11, 0x12, 0x13, 0x14,
0x22, 0x22, 0x22, 0x22,
0x33, 0x33, 0x33, 0x33,
0x44, 0x44, 0x44, 0x44}
dest[0] = binary.LittleEndian.Uint32(src[0:4])
dest[1] = binary.LittleEndian.Uint32(src[4:8])
dest[2] = binary.LittleEndian.Uint32(src[8:12])
dest[3] = binary.LittleEndian.Uint32(src[12:16])
fmt.Printf("X X X X\n", dest[0], dest[1], dest[2], dest[3])
}
Can I convert an array of byte in array of uint32 with a single instruction without use C.memcpy? I tried to use copy but give error. I know I can use this istruction
C.memcpy(unsafe.Pointer(&dest[0]), unsafe.Pointer(&src[0]), 16)
I'd like to understand if exist a valid alternative
CodePudding user response:
unsafe.Pointer
is the way to bypass the Go type system, with all the caveats of using the unsafe
package. To get the equivalent of memcpy
, you would pass your dest
slice to copy
like so: https://play.golang.org/p/MFJjHhDZatl
copy(unsafe.Slice((*byte)(unsafe.Pointer(&dest[0])), len(src)), src)
However, I would still make sure to run some benchmarks to ensure that your use case actually benefits from this type of optimization. Most situations can use safer methods without noticeable impact on performance.