golang 기본 함수에서는 UUID 관련 패키지를 제공하지 않습니다.
하지만 다행이도 google에서 golang용 uuid 패키지(https://github.com/google/uuid)를 github를 통해 제공하고 있네요.
이쯤이면 golang 기본 함수로 제공하면 되지 않을까? 하고 생각하지만... 뭐.. 제공해주는게 어디인가 싶습니다.
기본 사용법은 우선 아래와 같이 go get 명령어를 통해 패키지를 설치하고 github.com/google/uuid 패키지를 import 하여 사용하면 됩니다. 해당 package에 대한 상세 설명은 godoc(https://pkg.go.dev/github.com/google/uuid)을 참고하세요.
uuid package install
go get github.com/google/uuid
random uuid generate example
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
u := uuid.New()
fmt.Println(u)
fmt.Println(u.string())
}
출력 결과
adb86d48-ee36-450b-940e-246c7649be82
adb86d48-ee36-450b-940e-246c7649be82
uuid.New() 상세 설명
uuid.New() 함수는 아래와 같이를 uuid.NewRandom()함수를 사용하여 uuid를 생성하고 uuid.Must()를 통해 uuid, err를 체크하는 동작을 구현하고 있다.
uuid.Must(uuid.NewRandom())
1) uuid.NewRandom()를 이용하여 uuid 생성
2) uuid.Must()를 이용하여 uuid 유효성 체크
- 에러가 없으면 uuid return
- 에러가 발생한 경우 panic 발생
만약 panic 이 발생하기를 원하지 않는 경우 uuid.NewRandom()을 직접 호출하여 에러처리를 하는 방법도 있다.
uuid.NewRandom() 를 직접 호출하여 random uuid 생성 코드 예제
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
u, e := uuid.NewRandom()
if e != nil {
fmt.Println(e)
return
}
fmt.Println(u)
}
출력 결과
5ab2c17e-e681-4bec-aa1c-7abfdeb03a99
Random UUID를 생성하는 방법으로는 Version 1 인 uuid.NewUUID()를 사용하는 방법도 있다.
uuid.NewUUID() 를 사용하여 random uuid 생성 코드 예제
package main
import (
"fmt"
"github.com/google/uuid"
)
var namespace = uuid.NameSpaceURL
var url = []byte("takeanoteof.tistory.com")
func main() {
u, e := uuid.NewUUID()
if e != nil {
fmt.Println(e)
return
}
fmt.Println(u)
}
출력 결과
e25d6932-73cb-11ed-b2fd-acde48001122
random uuid를 생성하는 Versrion 1과 Version 4의 차이는 random 값을 생성할 때 사용되는 방법에 있습니다.
Version 4에서는 'crypto/rand' package를 사용하고 있으며, 중복된 비트가 생성될 가능성은 0.00000000006(6 × 10−11) 정도라고 합니다.
Version 1의 경우 NodeID, Clock Sequence, Current Time을 기반으로 UUID를 생성합니다. 기본적으로 시간 값을 가지고 UUID를 생성하기 때문에 Version 4보다는 중복된 비트가 생성될 가능성이 높다고 얘기하기도 합니다.
때문에 Random UUID를 생성할 때 Version 4인 uuid.New(), uuid.NewRandom()이 많이 사용되기도 합니다.
개인적으로 Version 1을 사용했을 때도 아직 한번도 중복된 값을 경험해본적이 없기 때문에, 크게 상관이 있을까 싶기도 하면서..
괜시리 코드 작성 시 Version 4 코드를 많이 사용하게 되네요...ㅎ
UUID와 관련하여 간략하게 잘 설명한 블로그가 있어서 추천 드립니다. 한번씩 읽어보시면 많은 도움이 되실 것 같아요.
https://go-recipes.dev/how-to-generate-uuids-with-go-be3988e771a6
위 블로그에서 UUID 생성 관련하여 benchmark 결과를 공개했는데 version 4가 가장 빠르다고 합니다.
그래서 저도 제 PC에서 UUID 생성관련하여 benchmark를 돌려봤어요. 위 블로그에서 제공했던 코드에서 아래와 같이 Version 2를 추가했습니다.
UUID Benchmark result
Benchmark Code (reference -> https://go-recipes.dev/how-to-generate-uuids-with-go-be3988e771a6)
package main
import (
"testing"
"github.com/google/uuid"
)
func BenchmarkGenerateV1(b *testing.B) {
for i := 0; i < b.N; i++ {
uuid.NewUUID()
}
}
func BenchmarkGenerateV2(b *testing.B) {
for i := 0; i < b.N; i++ {
uuid.NewDCEGroup()
}
}
func BenchmarkGenerateV3(b *testing.B) {
for i := 0; i < b.N; i++ {
uuid.NewMD5(namespace, url)
}
}
func BenchmarkGenerateV4(b *testing.B) {
for i := 0; i < b.N; i++ {
uuid.New()
}
}
func BenchmarkGenerateV5(b *testing.B) {
for i := 0; i < b.N; i++ {
uuid.NewSHA1(namespace, url)
}
}
Benchmark Result : verion 1- fastest, version 4 - slowest
$ go test -bench=. -v
goos: darwin
goarch: amd64
pkg: awesomeProject2/uuid
cpu: Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
BenchmarkGenerateV1
BenchmarkGenerateV1-16 11128141 100.9 ns/op
BenchmarkGenerateV2
BenchmarkGenerateV2-16 2176666 540.4 ns/op
BenchmarkGenerateV3
BenchmarkGenerateV3-16 6657812 179.3 ns/op
BenchmarkGenerateV4
BenchmarkGenerateV4-16 906026 1416 ns/op
BenchmarkGenerateV5
BenchmarkGenerateV5-16 5191666 227.7 ns/op
PASS
ok awesomeProject2/uuid 7.513s
신기하게도 제 PC에서는 Version 1이 가장 빨랐고, Version 4가 가장 느렸습니다. 혹시나 uuid.New()가 Must() 함수를 한번 거치기 때문에 느리지 않을까 하는 생각으로 uuid.NewRandom()으로 테스트를 수행했지만 결과는 비슷했습니다.
성능을 생각했을 때는 Version 1 uuid.NewUUID()를 사용하는 것도 좋은 선택일 것 같습니다.
역시 공개된 Benchmark는 참고용일 뿐 개인 환경마다 차이가 있음을 다시 한번 확인하게 된 계기인 것 같습니다.
'golang (go)' 카테고리의 다른 글
golang - const와 iota로 enum(열거)형 구현하기 (1) | 2023.11.18 |
---|---|
golang byte slice (array) compare (0) | 2023.02.07 |
golang type conversion [string(val)], type assertion [val.(string)] (0) | 2023.02.03 |
golang slice or array element(item) remove (delete) (0) | 2023.01.16 |
golang download & install (MAC) (0) | 2022.10.10 |
댓글