golang-goruntime与channel:高效的channel
来源:互联网 发布:淘宝宝贝降权查询 编辑:程序博客网 时间:2024/04/27 23:11
golang有两个非常大的特性,那就是goruntime与channel,这两个特性直接将开发人员从并发和线程同步中解放了出来,使高并发和线程同步之间代码的编写变得异常简单,并且占用资源少,同步传输效率高。
资源占用方面,goroutine 会从4096字节的初始栈内存占用开始按需增长或缩减内存占用。同步传输效率方面,我曾经在松本行弘的《代码的未来》一书上看到一个简洁的例子(书上的代码中行末带有分号,目前golang中已经取消了源代码中行末的分号,由编译器代为添加,一行代码包含多个语句则需要分号分隔)。下列代码在原代码基础上做了适当调整。
package main import ( "fmt" "time" ) func chanFlow(left, right chan int, bufferLen int) { if bufferLen <= 0 { left <- 1 + <-right } else { for i := 0; i < bufferLen; i++ { left <- 1 + <-right } } } func main() { nruntime := 100000 lastChan := make(chan int) var left chan int = nil right := lastChan begin := time.Now() fmt.Println("begin at:", begin) for i := 0; i < nruntime; i++ { left, right = right, make(chan int) go chanFlow(left, right, 0) } right <- 0 result := <-lastChan end := time.Now() fmt.Println("end at:", end, time.Since(begin)) fmt.Println(result) }
程序创建了10w零1个无缓冲channel, 10w个goruntime, 数据在goruntime中从第一个channel流向最后一个channel,每流入一次数值加一。代码在我的笔记本(2.7 GHz Intel Core i5, 8 GB 1867 MHz DDR3)运行结果如下:
begin at: 2016-08-28 14:42:04.972728029 +0800 CST
end at: 2016-08-28 14:42:05.454288408 +0800 CST 481.560725ms
耗时不到半秒。上面的例子中使用的是无缓冲的channel,把代码修改为带1000个单位缓冲的channel再试试看,代码如下:
func chanFlow(left, right chan int, bufferLen int) {...} func main() { nruntime := 100000 chanBuffer := 1000 result := make([]int, 0, 100) lastChan := make(chan int, chanBuffer) var left chan int = nil right := lastChan begin := time.Now() fmt.Println("begin at:", begin) for i := 0; i < nruntime; i++ { left, right = right, make(chan int, chanBuffer) go chanFlow(left, right, chanBuffer) } for i := 0; i < chanBuffer; i++ { right <- 0 } for i := 0; i < chanBuffer; i++ { result = append(result, <-lastChan) } end := time.Now() fmt.Println("end at:", end, time.Since(begin)) fmt.Println(result) }
运行结果如下:
begin at: 2016-08-28 14:54:09.352472708 +0800 CST
end at: 2016-08-28 14:54:14.155240335 +0800 CST 4.802767822s
不到5秒的时间,1000个数据在10w个goruntime中穿过了10w零1个channel。而在实际生产中,更多的需要传递的数据是字符串,那么现在把代码再修改一下试试,代码如下:
package main import ( "crypto/rand" "encoding/base64" "fmt" "io" "time" ) func chanFlow(left, right chan string, bufferLen int) { if bufferLen <= 0 { left <- <-right } else { for i := 0; i < bufferLen; i++ { left <- <-right } } } func genString() string { b := make([]byte, 32) if _, err := io.ReadFull(rand.Reader, b); err != nil { return "" } else { return base64.URLEncoding.EncodeToString(b) } } func main() { nruntime := 100000 chanBuffer := 1000 result := make([]string, 0, 100) lastChan := make(chan string, chanBuffer) dataForChan := make([]string, 0, chanBuffer) for i := 0; i < chanBuffer; i++ { dataForChan = append(dataForChan, genString()) } var left chan string = nil right := lastChan begin := time.Now() fmt.Println("begin at:", begin) for i := 0; i < nruntime; i++ { left, right = right, make(chan string, chanBuffer) go chanFlow(left, right, chanBuffer) } for i := 0; i < chanBuffer; i++ { right <- dataForChan[i] } for i := 0; i < chanBuffer; i++ { result = append(result, <-lastChan) } end := time.Now() fmt.Println("end at:", end, time.Since(begin)) fmt.Println(result) }
运行结果如下:
begin at: 2016-08-28 15:06:25.349599328 +0800 CST
end at: 2016-08-28 15:06:31.288183546 +0800 CST 5.938584364s
不到6秒的时间,1000个44字节的随机字符串在10w个goruntime中穿过了10w零1个channel。而1w个44字节的随机字符串在1w个goruntime中穿过了1w零1个channel耗时约为5秒。
以上可以看出,golang中数据在goruntime中通过channel同步的效率非常高。本文来自:CSDN博客
感谢作者:changjixiong
查看原文:golang-goruntime与channel:高效的channel
查看原文:http://www.zoues.com/2016/10/20/golang-goruntime%e4%b8%8echannel%e9%ab%98%e6%95%88%e7%9a%84channel/
- golang-goruntime与channel:高效的channel
- golang-goroutine与channel:高效的channel
- golang-goroutine与channel:高效的channel
- golang 的channel
- golang的channel使用
- golang的channel剖析
- golang的Channel
- golang的Channel
- golang的Channel
- golang channel 的使用
- golang:channel
- Golang:有趣的 channel 应用
- Golang:有趣的 channel 应用
- golang控制channel的出入口
- GoLang channel 用法转的
- golang channel的使用技巧
- golang channel的使用技巧
- golang channel的设计瑕疵
- golang积累-接口指针与结构体指针
- golang 远程传输文件
- Storm入门简介
- 用Golang写一个搜索引擎(0xFF)
- Golang不使用MD5比较文件内容是否一致
- golang-goruntime与channel:高效的channel
- 国内可用免费语料库
- Android实现登录邮箱的自动补全功能
- golang:errors
- PHP.10-PHP实例(一)-简单的计算器
- golang生产者与消费者
- 再论 golang 环境配置建议
- Golang实现基于Websocket协议的H5聊天室(上)
- golang:interface{}类型测试