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

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

golang循環初始比剩余慢

golang循環初始比剩余慢

Go
蝴蝶刀刀 2023-06-19 16:04:14
我是 golang 的新手,在做這個 poc 時,我注意到在運行 for 循環時有一個奇怪的行為。    package main;    import (        "log"        "strings"        "time"    )    type data struct {        elapseTime int64        data string    }    func main(){        for i := 0 ; i < 10; i++{            c := make(chan data);            go removeDuplicates("I love oranges LALALA I LOVE APPLES LALALA XD", c);            log.Printf("%v", <- c);        }    }    func removeDuplicates(value string , c chan data){        start := time.Now();        var d = data{};        var r string;        value = strings.ToLower(value);        var m = make(map[string]string);        splitVals := strings.Split(value, " ");        for _, element := range splitVals {            if _, ok := m[element]; ok == false {                m[element] = element;            }        }        for k, _ := range m {            r = r + k + " ";        }        d.data = strings.TrimRight(r, "");        d.elapseTime = time.Since(start).Nanoseconds();        c <- d;    }實際上,我想要實現的是刪除一個簡單字符串的重復項,并將這些信息連同所花費的時間一起打印出來。一個循環通過 go routine 運行 10 次,等待通過通道的響應。2019/05/24 00:55:49 {18060 i love oranges lalala apples xd }2019/05/24 00:55:49 {28930 love oranges lalala apples xd i }2019/05/24 00:55:49 {10393 i love oranges lalala apples xd }2019/05/24 00:55:49 {1609 oranges lalala apples xd i love }2019/05/24 00:55:49 {1877 i love oranges lalala apples xd }2019/05/24 00:55:49 {1352 i love oranges lalala apples xd }2019/05/24 00:55:49 {1708 i love oranges lalala apples xd }2019/05/24 00:55:49 {1268 apples xd i love oranges lalala }2019/05/24 00:55:49 {1736 oranges lalala apples xd i love }2019/05/24 00:55:49 {1037 i love oranges lalala apples xd }這是我所看到的:循環的前幾次打?。o論是單循環還是 100x 循環都無關緊要)將比循環的其余部分慢得多。這是有原因的嗎?(執行時間以納秒為單位)編輯:刪除開關部分,因為人們對這個問題感到困惑。
查看完整描述

1 回答

?
墨色風雨

TA貢獻1853條經驗 獲得超6個贊

并發不是并行。通道的這種特殊使用結果與僅從 返回值非常相似removeDuplicates,只是兩個 goroutine 需要協調它們對通道的使用會產生額外的開銷。

具體來說:

  • 循環的每次迭代都有自己的通道,每個通道只能容納一個元素。

  • 在所有語句都已執行之前,循環無法繼續下一次迭代,包括對該語句的調用log.Printf阻塞,直到從通道接收到值。

  • removeDuplicates檢測到實時時間已經過去了多少,而不是在解決問題上花費了多少時間。這是評論說它首先不是一個很好的基準的眾多原因之一。

推測:在循環的前幾次迭代中,goroutine 可能removeDuplicates會初始化start,然后將執行時間交給主 goroutine。然后 main goroutine 立即檢查 mutex on?c,發現它還不能做任何事情,并返回給調度程序,所有這些檢查和上下文切換增加了數千納秒(關心這通常是微基準測試的味道到goroutineremoveDuplicates的實時執行。main在幾次迭代之后,某些東西(也許是 Go 運行時)發現了在返回之前永遠無法取得進展的事實removeDuplicates,并且避免了上下文切換。

我知道此時您對解釋比建議更感興趣,但如果我不指出比較 Go 和 Java 的基準已經存在,我會覺得很不負責任。即使您想自己編寫,我也建議使用類似的方法:根據需要完成的任務定義基準程序,然后使用每種語言(或框架)中可用的最佳工具來完成工作具有良好的性能。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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