第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

golang:如何有效地模擬聯(lián)合類型

golang:如何有效地模擬聯(lián)合類型

Go
溫溫醬 2021-10-25 16:15:21
眾所周知,go 沒有聯(lián)合類型,只能通過接口模擬。我嘗試了兩種方法來模擬聯(lián)合,但結果遠不如C。package mainimport (    "fmt"    "time")type U interface {    i32() int32    i16() int16}type i32 int32func (u i32) i32() int32 {    return int32(u)}func (u i32) i16() int16 {    return int16(u)}type i16 int16func (u i16) i32() int32 {    return int32(u)}func (u i16) i16() int16 {    return int16(u)}func test() (total int64) {    type A struct {        t int32        u interface{}    }    a := [...]A{{1, int32(100)}, {2, int16(3)}}    for i := 0; i < 5000000000; i++ {        p := &a[i%2]        switch p.t {        case 1:            total += int64(p.u.(int32))        case 2:            total += int64(p.u.(int16))        }    }    return}func test2() (total int64) {    type A struct {        t int32        u U    }    a := [...]A{{1, i32(100)}, {2, i16(3)}}    for i := 0; i < 5000000000; i++ {        p := &a[i%2]        switch p.t {        case 1:            total += int64(p.u.i32())        case 2:            total += int64(p.u.i16())        }    }    return}type testfn func() int64func run(f testfn) {    ts := time.Now()    total := f()    te := time.Now()    fmt.Println(total)    fmt.Println(te.Sub(ts))}func main() {    run(test)    run(test2)}結果:2575000000001m23.508223094s25750000000034.95081661s方法方式更好,類型轉換方式花費更多的CPU時間。
查看完整描述

3 回答

?
慕妹3146593

TA貢獻1820條經(jīng)驗 獲得超9個贊

您可以使用數(shù)組將單個表示int32為兩個int16s,然后按照 Rob Pike 的建議將它們組合起來:


func test3() (total int64) {

    type A struct {

        t int32

        u [2]int16

    }

    a := [...]A{

        {1, [2]int16{100, 0}},

        {2, [2]int16{3, 0}},

    }


    for i := 0; i < N; i++ {

        p := &a[i%2]

        switch p.t {

        case 1:

            total += int64(p.u[0]<<0 | p.u[1]<<8)

        case 2:

            total += int64(p.u[0])

        }

    }

    return

}

使用原始的 Go 編譯器,它的運行速度比 C 版本慢約 2 倍,而使用 gccgo (-O3) 時,它的運行速度與 C 一樣快。


但請注意,這種方法假定小端整數(shù)。您需要切換大端架構的轉換順序。


此外,如果您需要從字節(jié)切片解碼結構,您應該真正使用encoding/binary. 創(chuàng)建這個庫是為了在字節(jié)序列和其他類型之間進行轉換。


查看完整回答
反對 回復 2021-10-25
?
慕田峪4524236

TA貢獻1875條經(jīng)驗 獲得超5個贊

聯(lián)合可能包含數(shù)字類型和八位字節(jié)字符串,因此我嘗試使用字節(jié)切片作為值容器并unsafe.Pointer根據(jù)具體類型使用它。


func test3() (total int64) {

    type A struct {

        t int32

        u []byte

    }   


    a := [...]A{{1, make([]byte, 8)}, {2, make([]byte, 8)}}

    *(*int32)(unsafe.Pointer(&a[0].u)) = 100 

    *(*int16)(unsafe.Pointer(&a[1].u)) = 3 


    for i := 0; i < 5000000000; i++ {

        p := &a[i%2]

        switch p.t {

        case 1:

            total += int64(*(*int32)(unsafe.Pointer(&p.u)))

        case 2:

            total += int64(*(*int16)(unsafe.Pointer(&p.u)))

        }   

    }   

    return

}

結果:


$ go run union.go

257500000000

12.844752701s


$ go run -compiler gccgo -gccgoflags -O3 union.go

257500000000

6.640667s

它是最好的版本嗎?


查看完整回答
反對 回復 2021-10-25
  • 3 回答
  • 0 關注
  • 426 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號