【问题标题】:Is there a faster way to make GET requests in Go?有没有更快的方法在 Go 中发出 GET 请求?
【发布时间】:2016-09-23 12:05:24
【问题描述】:

考虑这个程序:

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()

分析

我对此进行了相当多的调查。以下是我采取的一些方法:

  1. io.Copy 中使用不同的缓冲区大小
  2. 使用其他读取器/写入器
  3. 并发/并行
  4. 下载较大的文件

不同的缓冲区大小

我使用io.CopyBuffer 尝试了许多不同的缓冲区大小,我发现32KB 的默认缓冲区大小让我获得了最佳速度(仍然比wget 和Python 的reqeusts 慢1.6 到1.8 倍)。

其他读取器/写入器

所有其他读取器和写入器都比使用io.Copy 慢得可以忽略不计。我尝试使用 (f *File) Write 和其他一些缓冲读取器/写入器。

并发/并行

我什至编写了一个相当长的程序,它在标头中使用range 来并行下载此文件,但正如预期的那样,我的速度似乎没有任何显着提高。

更大的文件

我下载的文件是这个文件的三倍多,我的 Go 实现仍然比 wget 和 requests 慢 1.5 到 2 倍。

其他注意事项

  1. 在计时之前我正在构建一个二进制文件。
  2. 绝大多数时间都花在实际编写/复制response.Body 上。无论我下载的文件有多大,这部分似乎只占了大约 0.3 秒的经过时间。

那我做错了什么?我应该期望 GET 请求在 Go 中花费的时间更长吗?

【问题讨论】:

  • 什么版本的 go?
  • 你是在使用go run执行程序吗?
  • @MellowMarmot 不,我正在构建一个二进制文件,然后再计时。
  • @superfell 我正在使用 go version 1.7 darwin/amd64
  • wget 最有可能使用 gzip 但 go 没有。

标签: python http go wget


【解决方案1】:

我不知道该告诉你什么。我只是试图复制你的发现,但对我来说,所有 3 个版本所花费的时间大致相同

wget   8.035s  
go     8.174s
python 8.242s

也许在干净的 VM 或 docker 容器中尝试相同的实验?

【讨论】:

  • 我认为你是对的。今晚我将在 Arch 上使用 Go 1.7 试试这个。我会报告情况如何。关于为什么 Go 1.7 amd64/darwin 这样做有什么想法吗?
  • 我不确定。我在 linux/amd64 上使用 Go 1.7 运行了我的测试。您可能想查看 Go 1.7 中引入的全新 golang.org/pkg/net/http/httptrace 包。我自己还没有使用过它,但它看起来正是您调试它所需要的。
猜你喜欢
  • 2014-01-29
  • 1970-01-01
  • 2022-01-22
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 2023-04-10
  • 2015-05-06
相关资源
最近更新 更多