我正在处理从一台服务器上下载文件,并在操作将文件发送到另一台服务器之后。
文件大小可以从1MB到200MB不等。
目前,我的代码非常简单,我使用的是http.Client和bytes.Buffer。
需要花费大量时间来处理大量文件(100MB到200MB),其中有很多文件。
快速分析后,我发现大部分时间都是字节。(*缓冲区).grow,
如何为16MB创建大缓冲区?
为了提高代码效率,我该怎么办?处理大型http请求的一般提示?
修改
我将解释,正是我想要做的。 我有couchdb文件(附件),我试图复制到另一个couchdb实例。 couchdb文件大小可以从30MB到200MB,复制微小的(2-10MB)couchdb文件 - 非常快。
但通过电线发送文件真的很慢。 我目前正在尝试分析,并尝试使用@Evan回答来查看我的问题。
答案 0 :(得分:5)
查看bytes.NewBuffer
:http://golang.org/pkg/bytes/#NewBuffer
听起来你可以创建一个16MB的字节切片并用它来初始化缓冲区。
答案 1 :(得分:2)
如果您需要做的只是复制,您可以考虑您的程序无需保留内存中的数据这一事实。
现在,Go标准库的强大功能是对接口的合理使用:http.Response
的{{1}}成员实现了Body
接口,并且满足{{1}的类型1}} io.ReadCloser
的{{1}}方法的参数。
所以你可以像这样滚动:
执行文档请求 - 您将获得body
的实例,其中http.Client
成员的类型为Post
。
请注意,此时您还没有真正开始从“源”服务器接收正文,因为要这样做,您将不得不耗尽http.Response
的{{1}}。
发起另一个(假设Body
)请求发送数据,并在发出请求时提供第一步中获得的io.readCloser
成员。< / p>
完成此请求管道您的数据后,请致电io.ReadCloser
成员{/ 1}}。
这样的事情:
Body
在此代码中,POST
will read from src.Body
and then Close()
it itself。
你可能将Body
添加到混合中,希望减少执行的系统调用量,但除非普通方法不起作用,否则不要这样做。
答案 2 :(得分:1)
正如@Evan已经指出的那样:您可以在创建新缓冲区时选择初始缓冲区大小。
由于缓冲区的分配非常昂贵(这就是为什么grow
调用需要这么长时间;如果大小不再适合,它们会重新分配),选择正确的缓冲区大小是关键。选择正确的缓冲区分配策略取决于很多因素。您可以根据应用程序配置文件选择自己的增长缓冲区方法。
您还应该考虑回收缓冲区以防止堆碎片:http://blog.cloudflare.com/recycling-memory-buffers-in-go