Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance Golang在简单Web服务器上的高cpu使用率无法理解原因?_Performance_Go_Cpu Usage - Fatal编程技术网

Performance Golang在简单Web服务器上的高cpu使用率无法理解原因?

Performance Golang在简单Web服务器上的高cpu使用率无法理解原因?,performance,go,cpu-usage,Performance,Go,Cpu Usage,因此,我有一个简单的net/http Web服务器。它所做的只是提供100MB的随机字节,我打算将其用于网络速度测试。我的100mb端点处理程序非常简单(粘贴在下面)。代码运行良好,我得到了随机字节文件,问题是当我运行这个程序,有人下载这些100megabytes时,这个程序的CPU上升到150%,并一直保持到这个处理程序完成运行为止。我是不是做错了什么?我可以做些什么来提高此处理程序的性能 func downloadHandler(w http.ResponseWriter, r *http.

因此,我有一个简单的net/http Web服务器。它所做的只是提供100MB的随机字节,我打算将其用于网络速度测试。我的100mb端点处理程序非常简单(粘贴在下面)。代码运行良好,我得到了随机字节文件,问题是当我运行这个程序,有人下载这些100megabytes时,这个程序的CPU上升到150%,并一直保持到这个处理程序完成运行为止。我是不是做错了什么?我可以做些什么来提高此处理程序的性能

func downloadHandler(w http.ResponseWriter, r *http.Request) {
    str := RandStringBytes(8192); //generates 8192 bytes of randomness
    sz := 1000*1000*100; //100Megabytes
    iter := sz/len(str)+1;
    w.Header().Set("Content-Type", "application/octet-stream")
    w.Header().Set("Content-Length", strconv.Itoa( sz ))
    for i := 0; i < iter ; i++ {
        fmt.Fprintf(w, str )
    }
}
func下载处理程序(w http.ResponseWriter,r*http.Request){
str:=RandStringBytes(8192);//生成8192字节的随机性
sz:=1000*1000*100;//100兆字节
iter:=sz/len(str)+1;
w、 Header().Set(“内容类型”、“应用程序/八位字节流”)
w、 Header().Set(“内容长度”,strconv.Itoa(sz))
对于i:=0;i
问题在于需要一个格式字符串:

fmt.Fprint(w, str)
然后给它传递一个大的8KB格式字符串。
fmt
包必须分析格式字符串,它不能按原样到达输出。最明确的是,这是什么吃你的CPU

如果随机字符串包含特殊的
%
符号,这甚至会使您的情况更糟,因为
fmt.Fprintf()
可能需要更多您没有“传递”的参数,因此
fmt
包还必须(将)在输出中包含错误消息,例如:

fmt.Fprintf(os.Stdout, "aaa%bbb%d")
输出:

aaa%!b(MISSING)bb%!d(MISSING)
改为使用不需要格式字符串的:

fmt.Fprint(w, str)
或者更好的方法是,将随机字符串转换为字节片一次,然后继续编写:

data := []byte(str)
for i := 0; i < iter; i++ {
    if _, err := w.Write(data); err != nil {
        // Handle error, e.g. return
    }
}
数据:=[]字节(str)
对于i:=0;i

交付大量数据–您不会得到比在循环中写入准备好的字节片更快的解决方案(如果您改变片的大小,可能会稍微改变)。如果您的解决方案仍然“缓慢”,这可能是由于我们对您的
RandStringBytes()
函数一无所知,或者如果您使用其他处理程序或某些框架(使用相对较高的CPU),您的输出可能会被压缩(gzip)。此外,如果接收响应的客户端也在您的计算机上(例如浏览器),它-或防火墙/防病毒软件-可能会检查/分析响应中的恶意代码(可能也是资源密集型的)。

感谢您的回复,因此我尝试了您的建议->将字符串转换为字节片,这确实提高了性能,但似乎并没有减少cpuusage@freezingfire请参阅编辑后的答案以解决其他性能问题。RandStringBytes()只是用随机数据填充字节片,我在这个程序中没有其他处理程序,也没有防火墙或防病毒程序。最后,我创建了一个100Mb的随机文件,并使用http.ServeContent来交付它。现在我得到的最大CPU是60%,这是一个从150%大幅提高。