我正在Haskell中编写一个简单的https getter代码。收到响应后,我将其保存到压缩文件中。然而,与curl和gzip组合相比,我的版本非常慢。如何使卷曲更快?详情如下。
Haskell代码(fetcher.hs):
import Control.Lens
import qualified Codec.Compression.GZip as GZip
import qualified Data.ByteString.Lazy as BL
import Network.Wreq
writeURIBodyToFile :: FilePath -> String -> IO()
writeURIBodyToFile filePath uri = do
response <- get uri
let body = (response ^. responseBody)
BL.writeFile filePath (GZip.compress body)
main :: IO ()
main = writeURIBodyToFile "out.html.gz" "https://www.sahibinden.com/ilan/vasita-otomobil-seat-hatasiz-boyasiz-tramersiz-dsg-leon-469484363/detay/"
Haskell结果:
$ ghc -o fetcher fetcher.hs
$ time ./fetcher
real 0m9.240s
user 0m8.840s
sys 0m0.232s
卷曲结果:
$ time curl "https://www.sahibinden.com/ilan/vasita-otomobil-seat-hatasiz-boyasiz-tramersiz-dsg-leon-469484363/detay/" | gzip > out.html.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 102k 100 102k 0 0 331k 0 --:--:-- --:--:-- --:--:-- 332k
real 0m0.524s
user 0m0.156s
sys 0m0.040s
编辑: 我也尝试过使用http-conduit包,没有任何改变。
import qualified Data.ByteString.Lazy as BL
import Network.HTTP.Simple
main :: IO ()
main = do
response <- httpLBS "https://www.sahibinden.com/ilan/vasita-otomobil-seat-hatasiz-boyasiz-tramersiz-dsg-leon-469484363/detay/"
BL.writeFile "outnew.html" $ getResponseBody response
Edit2:我还检查了与tcpdump的连接,并且没有连接问题。
Edit3:GHCi, version 7.10.3
Edit4:编译命令ghc -o fetcher fetcher.hs
Edit5:2019年2月使用此代码无法重现该问题:
{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Simple
import qualified Data.ByteString.Char8 as B8
main :: IO ()
main = httpBS "https://www.sahibinden.com/ilan/vasita-otomobil-mercedes-benz-mercedes-benz-c-180-fascination-7g-tronic-ozel-renk-652750468/detay" >>= B8.putStrLn . getResponseBody
结果:
$ ghc -o fetcher fetcher.hs
$ time ./fetcher
real 0m0,549s
user 0m0,093s
sys 0m0,021s
Edit6:再次,问题无法在2019年2月的第一个代码示例中重现GHCi, version 8.0.2
答案 0 :(得分:3)
我最好的猜测是,您的HTTP客户端不考虑list_graph[idx]
HTTP头,而仅保留下载到远程服务器关闭连接,这是
a:可能比仅读Content-Length
标头要慢得多,许多Web服务器将套接字打开的时间比需要的长得多(通常用于套接字重用方案)
b:天真/简单的HTTP客户端之间的共同主题。
您可以使用如下的netcat http服务器来确认这一点:
Content-Length
现在点击http://127.0.0.1:9999并检查响应,经过优化以考虑printf "HTTP/1.0 200 OK\r\nContent-Length: 3\r\n\r\nabcx" | nc -l 9999
标头的http客户端将说响应正文为Content-Length
,而没有经过优化以考虑以下信息的http客户端abc
标头将指出响应正文为Content-Length
注意:此命令应在类似Unix的系统(Linux,* BSD,MacOS)上运行,但可能不适用于Windows系统。如果您正在运行Windows,它完全可以在Cygwin(也可能在WSL的工作,但我还没有尝试过,我还在滚动的Windows 7不支持WSL)