Python 有没有更快的方法在Go中发出GET请求?
考虑一下这个计划:Python 有没有更快的方法在Go中发出GET请求?,python,http,go,wget,Python,Http,Go,Wget,考虑一下这个计划: package main import ( "net/http" "os" ) var url = "https://upload.wikimedia.org/wikipedia/commons/f/fe/FlumeRide%2C_Liseberg_-_last_steep_POV.ogv" func main() { response, _ := http.Get(url) defer response.Body.Close()
package main
import (
"net/http"
"os"
)
var url = "https://upload.wikimedia.org/wikipedia/commons/f/fe/FlumeRide%2C_Liseberg_-_last_steep_POV.ogv"
func main() {
response, _ := http.Get(url)
defer response.Body.Close()
f, _ := os.Create("output.ogv")
defer f.Close()
_, err = io.Copy(f, response.Body)
}
它的功能与wget$url
相同,运行起来需要7.3秒(对我来说)wget
只需~4.6秒。为什么会有如此巨大的差异?这个简单的Python程序在将整个视频写入磁盘之前将其加载到内存中,大约需要5.2秒
import requests
url = "https://upload.wikimedia.org/wikipedia/commons/f/fe/FlumeRide%2C_Liseberg_-_last_steep_POV.ogv"
def main():
r = requests.get(url)
with open('output.ogv','wb') as output:
output.write(r.content)
if __name__ == "__main__":
main()
轮廓
我对此做了不少调查。以下是我采取的一些方法:
io.CopyBuffer
尝试了许多不同的缓冲区大小,发现默认的32KB缓冲区大小使我获得了最佳速度(仍然比wget
和Python的Requests
慢1.6到1.8倍)
其他读者/作者
所有其他读者和作者的速度都比使用io.Copy慢得多,这是可以忽略的。我尝试使用(f*File)Write
和一些其他缓冲读写器
并发/并行
我甚至编写了一个相当长的程序,在头文件中使用range
来并行下载这个文件,但正如预期的那样,我在速度上似乎没有任何显著的提高
大文件
我下载了一个比这个文件大三倍多的文件,我的Go实现仍然比wget和请求慢1.5到2倍
其他值得注意的事项
response.Body
上。不管我下载的文件有多大,这个部分似乎只占了大约0.3秒的时间那么我做错了什么?我是否应该期望GET请求在Go中花费更长的时间?我不知道该告诉你什么。我只是想复制你的发现,但对我来说,这三个版本所用的时间大致相同
wget 8.035s
go 8.174s
python 8.242s
也许在一个干净的VM或docker容器中尝试同样的实验?什么版本的go?你是否使用
go run
来执行程序?@MellowMarmot不,我在计时之前先构建一个二进制文件。@superfell我使用的是go版本1.7 darwin/AMD64,wget很可能使用gzip,但go没有。我认为你是对的。今晚我要在Arch上用Go 1.7试试这个。我会向你汇报情况的。有没有想过为什么Go 1.7 amd64/达尔文会这样做?我不确定。我在linux/amd64上用Go 1.7运行了测试。您可能想查看Go 1.7中引入的全新软件包。我自己还没有用过它,但它看起来正是调试它所需要的。