普通网友 2016-05-19 05:40
浏览 193

读取http.Response正文流

I'm sending a http request and getting a response in text/xml format. I don't need to parse the XML, just trying to return it as a string for testing. But it seems pretty slow.

The XML response is 278kb, but it can take about 1.7 but sometimes spike to 4.5seconds just to read the response body. I can rerun this over and over and it can vary wildly. I'm not sure what's causing it as i'm new to Go.

I feel like the ioutil.ReadAll() function is letting me down. But i've also tried bufio.NewReader and reader.ReadBytes. All seem to be just as slow.

this is what my function looks like:

client := &http.Client{}
req, err := http.NewRequest("POST", url, strings.NewReader(requestBody))
if err != nil {
    fmt.Println("New Request Error", err)
}

// Set Headers
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Content-Encoding", "gzip")
req.Header.Set("Accept-Encoding", "gzip, deflate")

defer req.Body.Close()

// Get Response
startRes := time.Now()
response, err := client.Do(req)
if response != nil {
    defer response.Body.Close()
}
if err != nil {
    fmt.Println("POST Error", err)
}
endRes := time.Now()
fmt.Println("Response took", endRes.Sub(startRes))

// Read Response Body
startRead := time.Now()
body, readErr := ioutil.ReadAll(response.Body)
if readErr != nil {
    fmt.Println("body error:", readErr)
    return nil, readErr
}

endRead := time.Now()
fmt.Println("Read response took:", endRead.Sub(startRead))

The output of these println's look like this:

> go run main.go
 Response took 5.230523s
 Read response took: 1.7551755s

Is there a way to make this code more efficient? I'm assuming the 1.7s read time for a 278kb file is due to network lag, right?

  • 写回答

1条回答 默认 最新

  • duangu1878 2016-05-19 07:13
    关注

    I recommend allocating a byte.Buffer and reading the body yourself. The code at ioutil.ReadAll creates a byte.Buffer at an initial capacity of Byte.MinRead (512 bytes).

    At 278KB, Buffer needs to expand, reallocate and recopy the returned byte array 10 times which is most processing time is being spent (for things you can control).

    Untested code to try below:

    buf := bytes.NewBuffer(make([]byte, 0, response.ContentLength))
    _, readErr = buf.ReadFrom(response.Body)
    body := buf.Bytes()
    
    评论

报告相同问题?

悬赏问题

  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?