亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

參考時間 % 12345 的“不穩定值”

參考時間 % 12345 的“不穩定值”

Go
冉冉說 2023-03-21 17:33:51
在這個反射器包中,它提到了一個不穩定的值被用作名稱后綴。它是對 12345 取模的納秒數。這是有意義的還是它只是偽隨機的同義詞,所以人類不會解釋它?// reflectorDisambiguator is used to disambiguate started reflectors.// initialized to an unstable value to ensure meaning isn't attributed to the suffix.var reflectorDisambiguator = int64(time.Now().UnixNano() % 12345)不穩定這個詞特別讓我不確定。在這種情況下是什么意思?與另一種獲取 12345 以下隨機數的方法相比,這樣做是否有優勢?
查看完整描述

1 回答

?
慕村9548890

TA貢獻1884條經驗 獲得超4個贊

意思似乎很清楚:

Kubernetes 提交:1da4f4a745bf536c34e377321a252b4774d1a7e0

工具/緩存/反射器.go

// reflectorDisambiguator is used to disambiguate started reflectors.
// initialized to an unstable value to ensure meaning isn't attributed to the suffix.

后綴行為不應該是確定性的,因為您不應該依賴特定的實現行為。


例如,類似的情況發生在 Go 地圖上:

Go 編程語言規范

對于帶有范圍子句的語句

未指定地圖上的迭代順序,并且不保證從一次迭代到下一次迭代是相同的。

Go 1 發行說明

在地圖中迭代

舊的語言規范沒有定義地圖的迭代順序,實際上它在不同的硬件平臺上是不同的。這導致在地圖上迭代的測試變得脆弱且不可移植,并且具有令人不快的特性,即測試可能總是在一臺機器上通過但在另一臺機器上失敗。

在 Go 1 中,使用 for range 語句遍歷映射時訪問元素的順序被定義為不可預測,即使同一個循環使用同一個映射運行多次也是如此。代碼不應假定以任何特定順序訪問元素。

此更改意味著依賴于迭代順序的代碼很可能會提前中斷并在成為問題之前很久就得到修復。同樣重要的是,即使程序使用范圍循環從地圖中選擇元素,它也允許地圖實現確保更好的地圖平衡。

Go 1.3 發行說明

地圖迭代

小地圖上的迭代不再以一致的順序發生。Go 1 定義“未指定映射的迭代順序,并且不保證從一個迭代到下一個迭代是相同的。” 為了避免代碼依賴于地圖迭代順序,Go 1.0 在地圖中的隨機索引處開始每個地圖迭代。Go 1.1 中引入的新 map 實現忽略了對具有 8 個或更少條目的 map 進行隨機迭代,盡管迭代順序仍然因系統而異。這允許人們編寫依賴于小地圖迭代順序的 Go 1.1 和 Go 1.2 程序,因此只能在某些系統上可靠地工作。Go 1.3 重新引入了小地圖的隨機迭代,以消除這些錯誤。

更新:如果代碼假定小地圖的迭代順序是固定的,它將中斷并且必須重寫以不做出該假設。因為只有小地圖受到影響,所以問題最常出現在測試中。


類似的擔憂導致了一項未實施的提案,以確保不穩定排序的順序是不穩定的:

建議:排序:以非確定性順序返回相等值#13884

瘋狂的想法,但是如果 sort.Sort 在開始之前隨機排列它的輸入呢?

Go 1.6 的 sort.Sort 與 Go 1.5 不同,我在谷歌看到至少有十幾個測試失敗是隱含地依賴于舊算法。通常的情況是您按結構中的一個字段對一片結構進行排序。如果存在該字段相等但其他不相等的條目,并且您希望最后的結構具有特定順序,則您依賴于 sort.Sort 的算法。稍后的 sort.Sort 可能會做出不同的選擇并產生不同的順序。這使得程序無法從一個版本的 Go 移植到另一個版本,就像用于使程序無法從一種體系結構移植到另一種體系結構的映射哈希差異一樣。我們通過稍微隨機化迭代順序來解決地圖問題。在 map 的情況下,它不是一個完整的排列,而是足以使測試明顯不穩定的變化。

我想知道我們是否應該對 sort.Sort 做同樣的事情。只需要 N 次交換就可以很好地洗牌,而且我們已經使用了 Nlog(N) 次交換,所以 N(log(N)+1) 不太可能被注意到。這也可以防止惡意輸入。

這會讓人們感到驚訝,尤其是那些認為 sort.Sort == sort.Stable 的人。但理由是,最好是在他們第一次運行代碼時讓他們感到驚訝,而不是在以后發布許多 Go 版本。


以下是time.Now()與以下各項相比的基準rand.Intn()

package main


import "testing"


import (

    rand "math/rand"

    "time"

)


// https://github.com/kubernetes/client-go/blob/79cb21f5b3b1dd8f8b23bd3f79925b4fda4e2562/tools/cache/reflector.go#L100

var reflectorDisambiguator = int64(time.Now().UnixNano() % 12345)


func BenchmarkTimeNow(b *testing.B) {

    for N := 0; N < b.N; N++ {

        reflectorDisambiguator = int64(time.Now().UnixNano() % 12345)

    }

}


// rand.Intn()

func init() {

    rand.Seed(time.Now().UnixNano())

    reflectorDisambiguator = int64(rand.Intn(12345))

}


func BenchmarkRandIntn(b *testing.B) {

    for N := 0; N < b.N; N++ {

        rand.Seed(time.Now().UnixNano())

        reflectorDisambiguator = int64(rand.Intn(12345))

    }

}

輸出:


$ go test disambiguator_test.go -bench=.

goos: linux

goarch: amd64

BenchmarkTimeNow-4      20000000            67.5 ns/op

BenchmarkRandIntn-4       100000         11941 ns/op

$


查看完整回答
反對 回復 2023-03-21
  • 1 回答
  • 0 關注
  • 114 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號