구글에서string이 []byte에 분배되어도 필기 복사를 하지 않는 방법을 고려해 보자
6812 단어 Go
구글에서
[]byte(str)
컴파일할 때 runtime.go
의 stringtoslicebyte
에 따라 바이트 배열에 복사됩니다.runtime.go
func stringtoslicebyte(s string) []byte {
b := rawbyteslice(len(s))
copy(b, s)
return b
}
그러나 실제로 구글은 내부적으로utf-8 문자열을 처리하기 때문에 직접 꺼내는 방법만 있으면 된다.그래서
unsafe
등장했어요...이걸 사용하면 스스로 프로그램을 파괴할 수 있어.
내부의 바이트는 말할 필요가 없다...
stringbytes.go
package main
import (
"fmt"
"unsafe"
)
func main() {
str := "hello, world!"
vec := *(*[]byte)(unsafe.Pointer(&str))
fmt.Println(vec)
}
포인터 연산까지 가능합니다!pointer.go
package main
import (
"unsafe"
)
type foo struct {
k int64
v int64
}
func main() {
f := &foo{3,4}
// unsafe.Pointer() で匿名ポインタにして
// uintptr() で演算可能にして
// +8 バイト(64bit)足して
// unsafe.Pointer で匿名ポインタに戻して
// そこにはフィールド v があるはずなので *int64 にキャストして
// デリファレンスすれば出来上がり
*(*int64)(unsafe.Pointer((uintptr(unsafe.Pointer(f))+8))) = 5 // グヒヒ
println(f.v) // 5
}
참고로 상술한 stringbytes.go
go tool 8g -S stringbytes.go
에서 어셈블러를 만들어 보면... 0x001c 00028 (stringbytes2.go:8) LEAL go.string."hello, world!"+0(SB),BX
0x0022 00034 (stringbytes2.go:8) MOVL (BX),CX
0x0024 00036 (stringbytes2.go:8) MOVL 4(BX),BP
0x0027 00039 (stringbytes2.go:9) MOVL CX,"".str+24(SP)
0x002b 00043 (stringbytes2.go:9) MOVL CX,(SP)
0x002e 00046 (stringbytes2.go:9) MOVL BP,"".str+28(SP)
0x0032 00050 (stringbytes2.go:9) MOVL BP,4(SP)
0x0036 00054 (stringbytes2.go:9) PCDATA $0,$0
0x0036 00054 (stringbytes2.go:9) CALL ,runtime.stringtoslicebyte(SB)
0x003b 00059 (stringbytes2.go:9) MOVL 8(SP),DX
0x003f 00063 (stringbytes2.go:9) MOVL 12(SP),CX
0x0043 00067 (stringbytes2.go:9) MOVL 16(SP),AX
※ 부분 발췌문이렇게 전선에 떨어진 건...
0x001c 00028 (stringbytes.go:9) LEAL go.string."hello, world!"+0(SB),BX
0x0022 00034 (stringbytes.go:9) MOVL (BX),BP
0x0024 00036 (stringbytes.go:9) MOVL BP,"".str+24(SP)
0x0028 00040 (stringbytes.go:9) MOVL 4(BX),BP
0x002b 00043 (stringbytes.go:9) MOVL BP,"".str+28(SP)
0x002f 00047 (stringbytes.go:10) LEAL "".str+24(SP),BX
0x0033 00051 (stringbytes.go:10) CMPL BX,$0
0x0036 00054 (stringbytes.go:10) JEQ $1,232
0x003c 00060 (stringbytes.go:10) MOVL (BX),DX
0x003e 00062 (stringbytes.go:10) MOVL 4(BX),CX
0x0041 00065 (stringbytes.go:10) MOVL 8(BX),BP
이렇게 생겼어!이렇게 하면 복사를 하지 않아도 문자열을 처리할 수 있다!
프로그램도 빨라졌어!
아무도 난처하지 않아!
모두 즐겁다!
모두들 힘껏 사용해라!
unsafe를 사용할 때 사용법과 용량을 엄격히 준수하십시오.레이스 컨디션이고 모든 경우에도 GC-safe가 아닙니다.
Reference
이 문제에 관하여(구글에서string이 []byte에 분배되어도 필기 복사를 하지 않는 방법을 고려해 보자), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/mattn/items/176459728ff4f854b165텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)