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

為了賬號(hào)安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

切片性能附加比分配具有更好的性能

切片性能附加比分配具有更好的性能

Go
慕妹3146593 2022-10-24 15:38:05
我試圖了解 Golang 中切片追加與分配的性能,我認(rèn)為通常分配會(huì)更好,但在這段代碼中,看起來追加更好。我試圖找出原因 - 但我正在努力解決這個(gè)問題。這是 Leetcode 中的合并排序數(shù)組,下面的版本 1 給了我 3 毫秒的運(yùn)行時(shí)間func merge(nums1 []int, m int, nums2 []int, n int)  {        tmpSlice := make([]int, m+n)    tmpIndex := 0    index1 := 0    index2 := 0        for index1 < m {        value1 := nums1[index1]        for index2 < n {            value2 := nums2[index2]            if value1 <= value2 {                break            } else {                tmpSlice[tmpIndex] = value2    \\ <-- Assign                index2++                tmpIndex++                      }        }        tmpSlice[tmpIndex] = value1    \\ <-- Assign        index1++        tmpIndex++     }        copy(nums1, tmpSlice[:tmpIndex])    copy(nums1[tmpIndex:], nums2[index2:])}下面的版本 2 給了我 0 毫秒的運(yùn)行時(shí)間func merge(nums1 []int, m int, nums2 []int, n int)  {       tmpSlice := make([]int, 0, m+n)    tmpIndex := 0    index1 := 0    index2 := 0        for index1 < m {        value1 := nums1[index1]        for index2 < n {            value2 := nums2[index2]            if value1 <= value2 {                break            } else {                tmpSlice = append(tmpSlice, value2)    \\ <-- Append                index2++                tmpIndex++                      }        }        tmpSlice = append (tmpSlice, value1)    \\ <-- Append        index1++        tmpIndex++     }        copy(nums1, tmpSlice[:tmpIndex])    copy(nums1[tmpIndex:], nums2[index2:])}兩個(gè)版本的唯一區(qū)別就是append vs assign,append速度更快。Append 正在檢查內(nèi)存分配,然后進(jìn)行分配,對嗎?Append 不應(yīng)該更慢嗎?
查看完整描述

1 回答

?
白衣非少年

TA貢獻(xiàn)1155條經(jīng)驗(yàn) 獲得超0個(gè)贊

我將兩者都放在基準(zhǔn)測試中,兩者之間的性能幾乎相等,append速度較慢,但幾乎可以忽略不計(jì)。


package main_test


import "testing"


func BenchmarkMerge1(b *testing.B) {

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

        num1 := []int{1, 2, 3}

        num2 := []int{4, 5, 6}

        merge1(num1, len(num1), num2, len(num2))

    }

}


func merge1(nums1 []int, m int, nums2 []int, n int) {


    tmpSlice := make([]int, m+n)

    tmpIndex := 0

    index1 := 0

    index2 := 0


    for index1 < m {

        value1 := nums1[index1]

        for index2 < n {

            value2 := nums2[index2]

            if value1 <= value2 {

                break

            } else {

                tmpSlice[tmpIndex] = value2 // <-- Assign

                index2++

                tmpIndex++

            }

        }

        tmpSlice[tmpIndex] = value1 // <-- Assign

        index1++

        tmpIndex++

    }


    copy(nums1, tmpSlice[:tmpIndex])

    copy(nums1[tmpIndex:], nums2[index2:])

}


func BenchmarkMerge2(b *testing.B) {

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

        num1 := []int{1, 2, 3}

        num2 := []int{4, 5, 6}

        merge2(num1, len(num1), num2, len(num2))

    }

}


func merge2(nums1 []int, m int, nums2 []int, n int) {

    tmpSlice := make([]int, 0, m+n)

    tmpIndex := 0

    index1 := 0

    index2 := 0


    for index1 < m {

        value1 := nums1[index1]

        for index2 < n {

            value2 := nums2[index2]

            if value1 <= value2 {

                break

            } else {

                tmpSlice = append(tmpSlice, value2) // <-- Append

                index2++

                tmpIndex++

            }

        }

        tmpSlice = append(tmpSlice, value1) // <-- Append

        index1++

        tmpIndex++

    }


    copy(nums1, tmpSlice[:tmpIndex])

    copy(nums1[tmpIndex:], nums2[index2:])

}

Running tool: /usr/local/go/bin/go test -benchmem -run=^$ -bench ^(BenchmarkMerge1|BenchmarkMerge2)$ example.com/m


goos: linux

goarch: amd64

pkg: example.com/m

cpu: Intel(R) Core(TM) i7-10870H CPU @ 2.20GHz

BenchmarkMerge1-16      34586568            36.40 ns/op       48 B/op          1 allocs/op

BenchmarkMerge2-16      32561293            36.77 ns/op       48 B/op          1 allocs/op

PASS

ok      example.com/m   2.533s

這是意料之中的,因?yàn)橹灰衅腥萘浚琣ppend 基本上就會(huì)進(jìn)行分配。append還增加len切片標(biāo)頭中的字段(該提示感謝@rustyx),這解釋了差異。


當(dāng)沒有在切片上設(shè)置初始容量并使用追加時(shí),您會(huì)看到更大的差異,因?yàn)樗鼤?huì)“增長”需要時(shí)間的底層數(shù)組。


如果我們更改tmpSlice := make([]int, 0, m+n)為tmpSlice := make([]int, 0)inmerge2我們會(huì)得到以下結(jié)果:


Running tool: /usr/local/go/bin/go test -benchmem -run=^$ -bench ^(BenchmarkMerge1|BenchmarkMerge2)$ example.com/m


goos: linux

goarch: amd64

pkg: example.com/m

cpu: Intel(R) Core(TM) i7-10870H CPU @ 2.20GHz

BenchmarkMerge1-16      37319397            32.34 ns/op       48 B/op          1 allocs/op

BenchmarkMerge2-16      14543529            87.75 ns/op       56 B/op          3 allocs/op

PASS

ok      example.com/m   2.604s

TL;DR,只要切片有容量,append就比分配慢(因?yàn)榍衅械淖侄芜f增)幾乎可以忽略不計(jì)len


查看完整回答
反對 回復(fù) 2022-10-24
  • 1 回答
  • 0 關(guān)注
  • 124 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)