Created
February 1, 2022 16:35
-
-
Save zzxvictor/29d9522b80f034887ed0485dd94d489e to your computer and use it in GitHub Desktop.
Golang UID Throughput
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"os" | |
"time" | |
) | |
var COUNTER_BIT_SIZE int = 14 | |
var THREAD_CAP int = 1 << COUNTER_BIT_SIZE | |
type WorkerVariant struct { | |
GeneratedId []chan int64 | |
workerID int64 | |
epoch int64 | |
threadCnt int | |
} | |
// 64 bits UID | |
func (w WorkerVariant) generateID(threadId int) { | |
prevTime := time.Now().UnixMilli() | |
counter := 0 | |
for { | |
currentTime := time.Now().UnixMilli() | |
if currentTime != prevTime { | |
prevTime = currentTime | |
counter = 0 | |
} else if counter >= THREAD_CAP { | |
time.Sleep(10 * time.Microsecond) | |
} else { | |
timeSinceEpoch := currentTime - w.epoch | |
id := timeSinceEpoch << 24 | |
id |= w.workerID << (COUNTER_BIT_SIZE + 4) | |
id |= int64(threadId) << COUNTER_BIT_SIZE | |
id |= int64(counter) | |
w.GeneratedId[threadId] <- id | |
counter ++ | |
} | |
} | |
} | |
func (w WorkerVariant) Start (){ | |
for i := 0; i < w.threadCnt; i ++ { | |
go w.generateID(i); | |
} | |
} | |
func (w WorkerVariant) benchmark() (float64) { | |
w.Start() | |
startCnt := 0 | |
for i := 0; i < w.threadCnt; i ++ { | |
startCnt += len(w.GeneratedId[i]) | |
} | |
startTime := time.Now().UnixMicro() | |
// | |
time.Sleep(200 * time.Millisecond) | |
endTime := time.Now().UnixMicro() | |
endCnt := 0 | |
for i := 0; i < w.threadCnt; i ++ { | |
endCnt += len(w.GeneratedId[i]) | |
} | |
duration := (endTime - startTime) / 1000.0 | |
return float64(endCnt - startCnt) / float64(duration) | |
} | |
func main() { | |
for threadCnt := 1; threadCnt <= 15; threadCnt ++ { | |
arr := make([]chan int64, threadCnt) | |
for i := 0; i < threadCnt; i ++ { | |
arr[i] = make(chan int64, 400 * THREAD_CAP) | |
} | |
worker := WorkerVariant{GeneratedId: arr, | |
workerID: 1, threadCnt: threadCnt, epoch: time.Now().UnixMilli()} | |
throughput := worker.benchmark() | |
fmt.Println(threadCnt, ",",int(throughput)) | |
} | |
os.Exit(0) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment