英文:
golang fast alternative to memcpy
问题
我有一个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("%04X %04X %04X %04X\n", dest[0], dest[1], dest[2], dest[3]);
return 0;
}
我正在将其迁移到Go语言,我不想使用C.memcpy,并且正在寻找一个快速的替代方法。这是我的代码:
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("%04X %04X %04X %04X\n", dest[0], dest[1], dest[2], dest[3])
}
我可以使用单个指令将字节数组转换为uint32数组,而不使用C.memcpy吗?我尝试使用copy函数,但出现错误。我知道我可以使用以下指令:
C.memcpy(unsafe.Pointer(&dest[0]), unsafe.Pointer(&src[0]), 16)
我想知道是否存在有效的替代方法。
英文:
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("%04X %04X %04X %04X\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("%04X %04X %04X %04X\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
答案1
得分: 7
unsafe.Pointer
是绕过Go类型系统的方法,使用unsafe
包时需要注意一些问题。要获得memcpy
的等效操作,你可以将dest
切片传递给copy
函数,示例如下:https://play.golang.org/p/MFJjHhDZatl
copy(unsafe.Slice((*byte)(unsafe.Pointer(&dest[0])), len(src)), src)
然而,我仍然建议运行一些基准测试,以确保你的使用场景实际上从这种优化中受益。大多数情况下,使用更安全的方法不会对性能产生明显影响。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论