關於golang隨機種子的注意點
go語言裡,在併發下,設定隨機數種子的方法(Seed())和隨機數其他方法(比如,Intn())是不能共存的。
背景:之前在一個專案裡需要生成隨機數,上線之後總是報有大量的499超時,程式碼各種優化到沒得優化也找不出問題,哪知最後逐行排查打時間戳,居然是隨機數的原因,隨機數的產生居然需要10來ms。
當時的程式碼產生隨機數是這兩句:
rand.Seed(time.Now().UnixNano())
rnd_int := rand.Intn(11)
後來查原始碼文件有說明:// Seed should not be called concurrently with any other Rand method.
所以以後還是想起他辦法去隨機數吧,比如給時間戳取模之類的、用shuffle()方法洗牌再取之類。
最後,寫了個小程式,可以壓測一下看看效果:
package main
import (
"fmt"
"math/rand"
"net/http"
"strconv"
"sync"
"time"
)
type Demo struct {
rnd *rand.Rand
Lock sync.RWMutex
}
func (d Demo) Get() int {
d.Lock.RLock()
defer d.Lock.RUnlock()
d.rnd.Seed(time.Now().UnixNano())
return d.rnd.Intn(11)
}
func main() {
// 最快
http.HandleFunc("/intn", func(w http.ResponseWriter, r *http.Request) {
t1 := time.Now().UnixNano() / 1e3
rnd_int := rand.Intn(11)
t2 := time.Now().UnixNano() / 1e3
fmt.Println(t2 - t1)
rnd_str := strconv.Itoa(rnd_int)
fmt.Fprintln(w, rnd_str, r.URL.Path)
})
// 不能併發取,會慢
http.HandleFunc("/seed", func(w http.ResponseWriter, r *http.Request) {
t1 := time.Now().UnixNano() / 1e3
rand.Seed(time.Now().UnixNano())
rnd_int := rand.Intn(10-0+1) + 0
t2 := time.Now().UnixNano() / 1e3
fmt.Println(t2 - t1)
rnd_str := strconv.Itoa(rnd_int)
fmt.Fprintln(w, rnd_str, r.URL.Path)
})
// 可以併發取,加了鎖
http.HandleFunc("/seedCon", func(w http.ResponseWriter, r *http.Request) {
t1 := time.Now().UnixNano() / 1e3
rObj := Demo{
rnd : rand.New(rand.NewSource(time.Now().UnixNano())),
}
rnd_int := rObj.Get()
t2 := time.Now().UnixNano() / 1e3
fmt.Println(t2 - t1)
rnd_str := strconv.Itoa(rnd_int)
fmt.Fprintln(w, rnd_str, r.URL.Path)
})
//監聽3000埠
http.ListenAndServe(":3000", nil)
}
wrk -t200 -c200 -d60s "http://127.0.0.1:3000/intn"
wrk -t200 -c200 -d60s "http://127.0.0.1:3000/seed"
wrk -t200 -c200 -d60s "http://127.0.0.1:3000/seedCon"
相關文章
- 需要提醒你關於 golang 中 map 使用的幾點注意事項Golang
- 隨機數種子(random seed)隨機random
- 關於Golang struct{}{}用法和注意事項GolangStruct
- C程式隨機種子原始碼C程式隨機原始碼
- 弱隨機化種子漏洞科普隨機
- 關於CORS 應該注意的幾點CORS
- Golang switch case 的使用注意點Golang
- unordered_map隨機底數種子隨機
- 關於如何產生隨機數的幾種方法彙總!(2018.07.08)隨機
- 關於MongoDB的幾點注意事項UMMongoDB
- pytorch---之隨機種子初始化PyTorch隨機
- GoLang 中的隨機數 tipsGolang隨機
- Golang - 關於 proto 檔案的一點小思考Golang
- golang split需要注意的一個點Golang
- 關於文化課(語文)老師的隨機點學號軟體有感隨機
- 關於golang的goroutine schedulerGolang
- wordpress的save_post鉤子注意點
- Golang生成區間隨機整數Golang隨機
- 運用JS 實現隨機點名 (隨機點名)JS隨機
- 有沒有關於物聯網創新的點子
- 關於golang的time包總結Golang
- numpy各種生成隨機數的方法隨機
- 人際關係的一點隨想
- jQuery 關於點選選單項,使子條目jQuery
- 關於AI、關於chatGPT的幾十種用法AIChatGPT
- 關於各種List型別特點以及使用的場景型別
- 幾種生成隨機數方法隨機
- equals中關於空格需要注意的地方
- 教你如何運用golang 實現陣列的隨機排序Golang陣列隨機排序
- golang隨筆3Golang
- 關於Golang中的依賴注入實現Golang依賴注入
- 關於難點的思考
- 關於在Vue中使用WebScoket的隨筆VueWeb
- 基於序列模型的隨機取樣模型隨機
- 【實用知識】關於“投標有效期”,這幾點要注意
- 策劃解讀:關於“暴擊”的誤解與數值的“偽隨機”隨機
- Golang 開源庫分享:faker - 隨機生成有趣的假資料!Golang隨機
- 關於python類屬性和例項屬性的一些細節注意點Python