github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/xunsafe/raw.go (about) 1 package xunsafe 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 // StringToBytes use a quick way to cast string to []byte without any alloc, in a 6000 length test, 9 // this is faster than `[]byte(string)` one 2200 times 10 // CAUTION: this is marked as unsafe so have limit, do not change the result. 11 // Generated asm code is: 12 // "".s2b STEXT nosplit size=88 args=0x28 locals=0x20 13 // 0x0000 00000 (main.go:33) TEXT "".s2b(SB), NOSPLIT|ABIInternal, $32-40 14 // 0x0000 00000 (main.go:33) SUBQ $32, SP 15 // 0x0004 00004 (main.go:33) MOVQ BP, 24(SP) 16 // 0x0009 00009 (main.go:33) LEAQ 24(SP), BP 17 // 0x000e 00014 (main.go:33) FUNCDATA $0, gclocals·9fad110d66c97cf0b58d28cccea80b12(SB) 18 // 0x000e 00014 (main.go:33) FUNCDATA $1, gclocals·7d2d5fca80364273fb07d5820a76fef4(SB) 19 // 0x000e 00014 (main.go:33) FUNCDATA $3, gclocals·ebb0e8ce1793da18f0378b883cb3e122(SB) 20 // 0x000e 00014 (main.go:33) FUNCDATA $4, "".s2b.stkobj(SB) 21 // 0x000e 00014 (main.go:35) PCDATA $2, $0 22 // 0x000e 00014 (main.go:35) PCDATA $0, $0 23 // 0x000e 00014 (main.go:35) XORPS X0, X0 24 // 0x0011 00017 (main.go:35) MOVUPS X0, "".bh(SP) 25 // 0x0015 00021 (main.go:35) MOVQ $0, "".bh+16(SP) 26 // 0x001e 00030 (main.go:36) MOVQ "".s+40(SP), AX 27 // 0x0023 00035 (main.go:36) MOVQ AX, "".bh(SP) 28 // 0x0027 00039 (main.go:37) MOVQ "".s+48(SP), AX 29 // 0x002c 00044 (main.go:37) MOVQ AX, "".bh+8(SP) 30 // 0x0031 00049 (main.go:38) PCDATA $0, $1 31 // 0x0031 00049 (main.go:38) MOVQ "".s+48(SP), CX 32 // 0x0036 00054 (main.go:38) MOVQ CX, "".bh+16(SP) 33 // 0x003b 00059 (main.go:40) PCDATA $2, $1 34 // 0x003b 00059 (main.go:40) MOVQ "".bh(SP), DX 35 // 0x003f 00063 (main.go:40) PCDATA $2, $0 36 // 0x003f 00063 (main.go:40) PCDATA $0, $2 37 // 0x003f 00063 (main.go:40) MOVQ DX, "".~r1+56(SP) 38 // 0x0044 00068 (main.go:40) MOVQ AX, "".~r1+64(SP) 39 // 0x0049 00073 (main.go:40) MOVQ CX, "".~r1+72(SP) 40 // 0x004e 00078 (main.go:40) MOVQ 24(SP), BP 41 // 0x0053 00083 (main.go:40) ADDQ $32, SP 42 // 0x0057 00087 (main.go:40) RET 43 func StringToBytes(str string) []byte { 44 strHeader := *(*reflect.StringHeader)(unsafe.Pointer(&str)) 45 sliceHeader := reflect.SliceHeader{ 46 Data: strHeader.Data, 47 Len: strHeader.Len, 48 Cap: strHeader.Len, 49 } 50 return *(*[]byte)(unsafe.Pointer(&sliceHeader)) 51 } 52 53 // StringToBytesFast is a faster version of StringToBytes. 54 // return stack space to store the final value, without the allocation of a temporary struct. 55 // Generated asm code is: 56 // "".s2bFast STEXT nosplit size=43 args=0x28 locals=0x0 57 // 0x0000 00000 (main.go:43) TEXT "".s2bV1(SB), NOSPLIT|ABIInternal, $0-40 58 // 0x0000 00000 (main.go:43) FUNCDATA $0, gclocals·39d1b96ca581879f548ad2c8aeb3a5fe(SB) 59 // 0x0000 00000 (main.go:43) FUNCDATA $1, gclocals·7d2d5fca80364273fb07d5820a76fef4(SB) 60 // 0x0000 00000 (main.go:43) FUNCDATA $3, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB) 61 // 0x0000 00000 (main.go:43) FUNCDATA $4, "".s2bV1.stkobj(SB) 62 // 0x0000 00000 (main.go:43) PCDATA $2, $0 63 // 0x0000 00000 (main.go:43) PCDATA $0, $1 64 // 0x0000 00000 (main.go:43) MOVQ $0, "".b+24(SP) 65 // 0x0009 00009 (main.go:43) XORPS X0, X0 66 // 0x000c 00012 (main.go:43) MOVUPS X0, "".b+32(SP) 67 // 0x0011 00017 (main.go:45) MOVQ "".s+16(SP), AX 68 // 0x0016 00022 (main.go:45) PCDATA $0, $2 69 // 0x0016 00022 (main.go:45) MOVQ "".s+8(SP), CX 70 // 0x001b 00027 (main.go:46) MOVQ CX, "".b+24(SP) 71 // 0x0020 00032 (main.go:47) MOVQ AX, "".b+32(SP) 72 // 0x0025 00037 (main.go:48) MOVQ AX, "".b+40(SP) 73 // 0x002a 00042 (main.go:49) RET 74 func StringToBytesFast(s string) (b []byte) { 75 bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) 76 sh := *(*reflect.StringHeader)(unsafe.Pointer(&s)) 77 bh.Data = sh.Data 78 bh.Len = sh.Len 79 bh.Cap = sh.Len 80 return b 81 } 82 83 // BytesToString use a quick way to cast []byte to string without any alloc, in a 6000 length test, 84 // this is faster than `string(bytes)` one 2200 times 85 func BytesToString(data []byte) string { 86 return *(*string)(unsafe.Pointer(&data)) 87 }