iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0

來看兩個程式來比較interface跟特定型別的效能

func BenchmarkGeneric(b *testing.B) {
	repeat := func(
		done <-chan interface{},
		values ...interface{},
	) <-chan interface{} {
		valueStream := make(chan interface{})
		go func() {
			defer close(valueStream)
			for {
				for _, v := range values {
					select {
					case <-done:
						return
					case valueStream <- v:
					}
				}
			}
		}()
		return valueStream
	}
	take := func(
		done <-chan interface{},
		valueStream <-chan interface{},
		num int,
	) <-chan interface{} {
		takeStream := make(chan interface{})
		go func() {
			defer close(takeStream)
			for i := 0; i < num; i++ {
				select {
				case <-done:
					return
				case takeStream <- <-valueStream:
				}
			}
		}()
		return takeStream
	}
	toString := func(
		done <-chan interface{},
		valueStream <-chan interface{},
	) <-chan string {
		stringStream := make(chan string)
		go func() {
			defer close(stringStream)
			for v := range valueStream {
				select {
				case <-done:
					return
				case stringStream <- v.(string):
				}
			}
		}()
		return stringStream
	}
	done := make(chan interface{})
	defer close(done)

	b.ResetTimer()
	for range toString(done, take(done, repeat(done, "a"), b.N)) {
	}
}

func BenchmarkTyped(b *testing.B) {
	repeat := func(done <-chan interface{}, values ...string) <-chan string {
		valueStream := make(chan string)
		go func() {
			defer close(valueStream)
			for {
				for _, v := range values {
					select {
					case <-done:
						return
					case valueStream <- v:
					}
				}
			}
		}()
		return valueStream
	}

	take := func(
		done <-chan interface{},
		valueStream <-chan string,
		num int,
	) <-chan string {
		takeStream := make(chan string)
		go func() {
			defer close(takeStream)
			for i := num; i > 0 || i == -1; {
				if i != -1 {
					i--
				}
				select {
				case <-done:
					return
				case takeStream <- <-valueStream:
				}
			}
		}()
		return takeStream
	}

	done := make(chan interface{})
	defer close(done)

	b.ResetTimer()
	for range take(done, repeat(done, "a"), b.N) {
	}
}


goos: darwin
goarch: arm64
BenchmarkGeneric
BenchmarkGeneric-10    	 1879737	       646.5 ns/op
BenchmarkTyped
BenchmarkTyped-10      	 3012214	       399.4 ns/op
PASS

BenchmarkGeneric 函數:

使用了 interface{} 作為參數和返回值,這意味著它是通用型的,可以用於任何數據類型。
定義了三個函數:repeat, take, 和 toString。其中,toString 函數將通用型 channel 的值轉換為 string 型別。
基准測試的工作流程是:先用 repeat 生成一連串的 "a" 字符串,然後用 take 從這些字符串中取 b.N 個值,最後用 toString 將這些值轉換為 string 並遍歷它們。

BenchmarkTyped 函數:

是專用型的,特定於 string 數據類型。這意味著這個函數在其內部只處理 string 數據類型,不使用 interface{}。
只定義了 repeat 和 take 兩個函數,因為我們已知輸入和輸出都是 string,所以不需要 toString 函數。
基准測試的工作流程是:先用 repeat 生成一連串的 "a" 字符串,然後用 take 從這些字符串中取 b.N 個值並遍歷它們。


上一篇
15.Pipeline
下一篇
17.Fan in, Fan out
系列文
Concurrency in go 讀書心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言