본문 바로가기
golang (go)

golang random UUID

by first author 2022. 12. 4.
728x90
반응형

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

 

How to generate UUIDs with Go

What are UUIDs and how do you generate them with Go

go-recipes.dev

 

위 블로그에서 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는 참고용일 뿐 개인 환경마다 차이가 있음을 다시 한번 확인하게 된 계기인 것 같습니다.

728x90
반응형

댓글