1 回答

TA貢獻1876條經驗 獲得超7個贊
沒有什么神秘之處。優化!
package blah
import (
"bytes"
"encoding/binary"
"testing"
)
func BenchmarkByteConversionLeast(t *testing.B) {
var i uint32 = 3419234848
buf := new(bytes.Buffer)
_ = binary.Write(buf, binary.BigEndian, i)
b := buf.Bytes()
for n := 0; n < t.N; n++ {
// Start with least significant bit: 0.27 nanos
value := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[2])<<16 | uint32(b[0])<<24
_ = value
}
}
func BenchmarkByteConversionMost(t *testing.B) {
var i uint32 = 3419234848
buf := new(bytes.Buffer)
_ = binary.Write(buf, binary.BigEndian, i)
b := buf.Bytes()
for n := 0; n < t.N; n++ {
// Start with most significant bit: 0.68 nanos
value := uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
_ = value
}
}
輸出:
go test silly_test.go -bench=.
goos: linux
goarch: amd64
BenchmarkByteConversionLeast-4 2000000000 0.72 ns/op
BenchmarkByteConversionMost-4 2000000000 1.80 ns/op
這應該是顯而易見的。邊界檢查消除。
只需使用常識。如果檢查索引 3、2、1 和 0 的數組邊界,則可以在 3 處停止檢查,因為顯然 2、1 和 0 也是有效的。如果檢查索引 0、1、2 和 3 的數組邊界,則必須檢查所有索引的邊界。一次邊界檢查與四次邊界檢查。
您還應該閱讀好的代碼,例如 Go 標準庫。例如,
func (littleEndian) PutUint64(b []byte, v uint64) {
_ = b[7] // early bounds check to guarantee safety of writes below
b[0] = byte(v)
b[1] = byte(v >> 8)
b[2] = byte(v >> 16)
b[3] = byte(v >> 24)
b[4] = byte(v >> 32)
b[5] = byte(v >> 40)
b[6] = byte(v >> 48)
b[7] = byte(v >> 56)
}
- 1 回答
- 0 關注
- 87 瀏覽
添加回答
舉報