• Go语言阅读小笔记,来自知呼达达关于unsafe.Pointer的分享.


    第一式 - 获得Slice和String的内存数据

    func stringPointer(s string) unsafe.Pointer {
    	p := (*reflect.StringHeader)(unsafe.Pointer(&s))
    	return unsafe.Pointer(p.Data)
    }
    
    func bytePointer(b []byte) unsafe.Pointer {
    	p := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    	return unsafe.Pointer(p.Data)
    }

    第二式 - 把[]byte转成string

    package test
    
    import "testing"
    import "unsafe"
    
    func Test_ByteString(t *testing.T) {
    	var x = []byte("Hello World!")
    	var y = *(*string)(unsafe.Pointer(&x))
    	var z = string(x)
    
    	if y != z {
    		t.Fail()
    	}
    }
    
    func Benchmark_Normal(b *testing.B) {
    	var x = []byte("Hello World!")
    	for i := 0; i < b.N; i ++ {
    		_ = string(x)
    	}
    }
    
    func Benchmark_ByteString(b *testing.B) {
    	var x = []byte("Hello World!")
    	for i := 0; i < b.N; i ++ {
    		_ = *(*string)(unsafe.Pointer(&x))
    	}
    }
    这个实验先证明了我们能够用[]byte的数据造个string给Go。接着做了两组Benchmark,分别測试了普通的类型转换和伪造string的效率。

    PASS
    Benchmark_Normal    20000000            63.4 ns/op
    Benchmark_ByteString    2000000000           0.55 ns/op
    ok      github.com/idada/go-labs/labs28 2.486s

    第三式 - 结构体和[]byte互转

    type MyStruct struct {
    	A int
    	B int
    }
    
    var sizeOfMyStruct = int(unsafe.Sizeof(MyStruct{}))
    
    func MyStructToBytes(s *MyStruct) []byte {
    	var x reflect.SliceHeader
    	x.Len = sizeOfMyStruct
    	x.Cap = sizeOfMyStruct
    	x.Data = uintptr(unsafe.Pointer(s))
    	return *(*[]byte)(unsafe.Pointer(&x))
    }
    
    func BytesToMyStruct(b []byte) *MyStruct {
    	return (*MyStruct)(unsafe.Pointer(
    		(*reflect.SliceHeader)(unsafe.Pointer(&b)).Data,
    	))
    }



  • 相关阅读:
    Rolling Hash(Rabin-Karp算法)匹配字符串
    vim下单行长文本的时候卡顿解决办法
    设置vim的默认工作路径同时与自动设当前编辑的文件所在目录为当前工作路径不冲突
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6839268.html
Copyright © 2020-2023  润新知