Skip to content

Instantly share code, notes, and snippets.

@tfausak
Last active October 27, 2017 20:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tfausak/afab233786cee3090f55974ffe0b1ba8 to your computer and use it in GitHub Desktop.
Save tfausak/afab233786cee3090f55974ffe0b1ba8 to your computer and use it in GitHub Desktop.
-- This is a small benchmark meant to see how fast the http-client library can
-- make requests. In particular, it's meant to compare the network library and
-- the socket library. <https://github.com/snoyberg/http-client/pull/306>
import qualified Control.Concurrent.Async as Async
import qualified Control.Monad as Monad
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Data.Text.Lazy as LazyText
import qualified Data.Text.Lazy.Encoding as LazyText
import qualified Data.Time as Time
import qualified Network.HTTP.Client as Client
import qualified Network.HTTP.Types as Http
import qualified Network.Wai as Wai
import qualified Network.Wai.Handler.Warp as Warp
import qualified Text.Printf as Printf
main :: IO ()
main = do
let
status = Http.status200
body = LazyText.encodeUtf8 (LazyText.pack "null")
port = 8080
server = Warp.run port (\ _ respond -> respond (Wai.responseLBS
status
[(Http.hContentType, Text.encodeUtf8 (Text.pack "application/json"))]
body))
threads = 4
count = 10000
thread <- Async.async server
request <- Client.parseRequest ("http://localhost:" ++ show port)
manager <- Client.newManager Client.defaultManagerSettings
start <- Time.getCurrentTime
Async.replicateConcurrently_ threads (Monad.replicateM_ count (do
response <- Client.httpLbs request manager
Monad.guard (Client.responseStatus response == status)
Monad.guard (Client.responseBody response == body)))
end <- Time.getCurrentTime
Async.cancel thread
let elapsed = Time.diffUTCTime end start
let rate = fromIntegral count / realToFrac elapsed
Printf.printf
"%d threads\n\
\%d requests per thread\n\
\%.1f requests per second\n"
threads
count
(rate :: Double)
# network
4 threads
10000 requests per thread
5113.8 requests per second
---
5,187,380,264 bytes allocated in the heap
99,635,672 bytes copied during GC
2,137,984 bytes maximum residency (40 sample(s))
46,288 bytes maximum slop
4 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 6057 colls, 0 par 0.237s 0.244s 0.0000s 0.0004s
Gen 1 40 colls, 0 par 0.045s 0.061s 0.0015s 0.0116s
TASKS: 8 (1 bound, 7 peak workers (7 total), using -N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.001s ( 0.010s elapsed)
MUT time 4.056s ( 5.633s elapsed)
GC time 0.272s ( 0.288s elapsed)
RP time 0.000s ( 0.000s elapsed)
PROF time 0.011s ( 0.016s elapsed)
EXIT time 0.000s ( 0.000s elapsed)
Total time 4.342s ( 5.932s elapsed)
Alloc rate 1,278,935,177 bytes per MUT second
Productivity 93.5% of total user, 94.7% of total elapsed
gc_alloc_block_sync: 0
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0
---
Fri Oct 27 14:51 2017 Time and Allocation Profiling Report (Final)
gh-306 +RTS -N -p -s -p -h -RTS
total time = 3.94 secs (3935 ticks @ 1000 us, 1 processor)
total alloc = 4,043,886,840 bytes (excludes profiling overheads)
COST CENTRE MODULE SRC %time %alloc
throwSocketErrorIfMinus1RetryMayBlock Network.Socket.Internal Network/Socket/Internal.hsc:(161,1)-(162,53) 16.6 1.3
MAIN MAIN <built-in> 14.2 9.3
httpRaw'.getConnectionWrapper Network.HTTP.Client.Core Network/HTTP/Client/Core.hs:(122,5)-(136,65) 13.0 4.4
parseStatusHeaders.withTimeout Network.HTTP.Client.Headers Network/HTTP/Client/Headers.hs:(30,5)-(32,73) 5.2 1.5
receiveloop Network.Wai.Handler.Warp.Recv Network/Wai/Handler/Warp/Recv.hs:(115,1)-(129,20) 3.8 0.8
connectionReadLineWith.go Network.HTTP.Client.Connection Network/HTTP/Client/Connection.hs:(43,5)-(53,57) 2.0 3.1
httpRaw'.getConnectionWrapper.timeSpentMicro Network.HTTP.Client.Core Network/HTTP/Client/Core.hs:132:29-77 1.4 0.9
getManagedConn.\.releaseHelper.\ Network.HTTP.Client.Manager Network/HTTP/Client/Manager.hs:(355,45)-(361,51) 1.4 0.4
serveConnection.processRequest Network.Wai.Handler.Warp.Run Network/Wai/Handler/Warp/Run.hs:(427,5)-(483,47) 1.1 0.2
withResponse Network.HTTP.Client.Core Network/HTTP/Client/Core.hs:50:1-71 1.1 0.2
parseStatusHeaders.strip Network.HTTP.Client.Headers Network/HTTP/Client/Headers.hs:96:5-71 1.0 1.3
makeConnection Network.HTTP.Client.Connection Network/HTTP/Client/Connection.hs:(88,1)-(121,9) 1.0 1.4
recv Network.Socket.ByteString Network/Socket/ByteString.hsc:(226,1)-(231,62) 0.8 8.4
httpRaw' Network.HTTP.Client.Core Network/HTTP/Client/Core.hs:(86,1)-(146,44) 0.7 1.6
foldCaseBS.toLower8' Data.CaseInsensitive.Internal Data/CaseInsensitive/Internal.hs:(190,7)-(194,37) 0.6 1.8
makeConnection.\ Network.HTTP.Client.Connection Network/HTTP/Client/Connection.hs:(110,36)-(113,62) 0.6 1.4
toByteString Blaze.ByteString.Builder Blaze/ByteString/Builder.hs:151:1-46 0.5 4.4
toByteStringIOWith Blaze.ByteString.Builder Blaze/ByteString/Builder.hs:(184,1)-(204,40) 0.2 32.5
# socket
4 threads
10000 requests per thread
4835.7 requests per second
---
5,230,164,096 bytes allocated in the heap
116,170,400 bytes copied during GC
2,172,656 bytes maximum residency (51 sample(s))
57,496 bytes maximum slop
5 MB total memory in use (1 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 6095 colls, 0 par 0.271s 0.277s 0.0000s 0.0001s
Gen 1 51 colls, 0 par 0.058s 0.061s 0.0012s 0.0022s
TASKS: 8 (1 bound, 7 peak workers (7 total), using -N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.001s ( 0.003s elapsed)
MUT time 4.337s ( 5.867s elapsed)
GC time 0.314s ( 0.321s elapsed)
RP time 0.000s ( 0.000s elapsed)
PROF time 0.014s ( 0.016s elapsed)
EXIT time 0.000s ( 0.000s elapsed)
Total time 4.669s ( 6.191s elapsed)
Alloc rate 1,205,922,182 bytes per MUT second
Productivity 92.9% of total user, 94.5% of total elapsed
gc_alloc_block_sync: 0
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0
---
Fri Oct 27 14:49 2017 Time and Allocation Profiling Report (Final)
gh-306 +RTS -N -p -s -p -h -RTS
total time = 5.23 secs (5233 ticks @ 1000 us, 1 processor)
total alloc = 4,078,055,760 bytes (excludes profiling overheads)
COST CENTRE MODULE SRC %time %alloc
MAIN MAIN <built-in> 16.2 9.7
wait.\ System.Socket.Internal.Platform platform/linux/src/System/Socket/Internal/Platform.hsc:(48,33)-(50,28) 16.1 0.6
httpRaw'.getConnectionWrapper Network.HTTP.Client.Core Network/HTTP/Client/Core.hs:(122,5)-(136,65) 11.2 4.4
parseStatusHeaders.withTimeout Network.HTTP.Client.Headers Network/HTTP/Client/Headers.hs:(30,5)-(32,73) 4.4 1.5
receiveloop Network.Wai.Handler.Warp.Recv Network/Wai/Handler/Warp/Recv.hs:(115,1)-(129,20) 3.8 0.8
unsafeSend.\ System.Socket.Unsafe src/System/Socket/Unsafe.hs:56:39-68 3.0 0.1
unsafeReceive.\ System.Socket.Unsafe src/System/Socket/Unsafe.hs:70:38-67 2.8 0.1
throwSocketErrorIfMinus1RetryMayBlock Network.Socket.Internal Network/Socket/Internal.hsc:(161,1)-(162,53) 2.3 0.2
connectionReadLineWith.go Network.HTTP.Client.Connection Network/HTTP/Client/Connection.hs:(42,5)-(52,57) 1.4 3.1
wait System.Socket.Internal.Platform platform/linux/src/System/Socket/Internal/Platform.hsc:(44,1)-(62,75) 1.2 0.2
getManagedConn.\.releaseHelper.\ Network.HTTP.Client.Manager Network/HTTP/Client/Manager.hs:(354,45)-(360,51) 1.0 0.4
makeConnection Network.HTTP.Client.Connection Network/HTTP/Client/Connection.hs:(87,1)-(120,9) 0.9 1.4
parseStatusHeaders.strip Network.HTTP.Client.Headers Network/HTTP/Client/Headers.hs:96:5-71 0.6 1.2
httpRaw' Network.HTTP.Client.Core Network/HTTP/Client/Core.hs:(86,1)-(146,44) 0.6 1.6
foldCaseBS.toLower8' Data.CaseInsensitive.Internal Data/CaseInsensitive/Internal.hs:(190,7)-(194,37) 0.6 1.8
toByteString Blaze.ByteString.Builder Blaze/ByteString/Builder.hs:151:1-46 0.4 4.3
makeConnection.\ Network.HTTP.Client.Connection Network/HTTP/Client/Connection.hs:(109,36)-(112,62) 0.3 1.4
receive System.Socket src/System/Socket.hsc:(379,1)-(381,75) 0.3 8.1
toByteStringIOWith Blaze.ByteString.Builder Blaze/ByteString/Builder.hs:(184,1)-(204,40) 0.2 32.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment