wsproto
wsproto copied to clipboard
over 10% regression in small message performance
using the newly minted bench/connection.py with some tweaks:
$ pip install wsproto==0.14.1 wsaccel
$ python bench/connection.py
4.636s elapsed, 93usec per iteration
$ pip install wsproto==1.0.0
$ python bench/connection.py
5.192s elapsed, 104usec per iteration
Benchmark patch follows. It should probably be expanded with command line args for count, message size, etc.
diff --git a/bench/connection.py b/bench/connection.py
index 6585944..bc10bfa 100644
--- a/bench/connection.py
+++ b/bench/connection.py
@@ -5,16 +5,16 @@ from typing import List
import wsproto
random_seed = 0
-mu = 125 * 1024
-sigma = 75 * 1024
-iterations = 5000
+mu = 125 #* 1024
+sigma = 75 #* 1024
+iterations = 50000
per_message_deflate = False
rand = random.Random(random_seed)
-client_extensions: List[wsproto.extensions.Extension] = []
+#client_extensions: List[wsproto.extensions.Extension] = []
if per_message_deflate:
pmd = wsproto.extensions.PerMessageDeflate()
offer = pmd.offer()
@@ -23,11 +23,11 @@ if per_message_deflate:
client_extensions.append(pmd)
client = wsproto.connection.Connection(
wsproto.ConnectionType.CLIENT,
- extensions=client_extensions,
+ #extensions=client_extensions,
)
-server_extensions: List[wsproto.extensions.Extension] = []
+#server_extensions: List[wsproto.extensions.Extension] = []
if per_message_deflate:
pmd = wsproto.extensions.PerMessageDeflate()
offer = pmd.offer()
@@ -35,23 +35,24 @@ if per_message_deflate:
pmd.accept(offer)
server = wsproto.connection.Connection(
wsproto.ConnectionType.SERVER,
- extensions=server_extensions,
+ #extensions=server_extensions,
)
start = time.perf_counter()
for i in range(iterations):
client_msg = b"0" * max(0, round(rand.gauss(mu, sigma)))
- client_out = client.send(wsproto.events.BytesMessage(client_msg))
+ client_out = client.send(wsproto.events.BytesMessage(data=client_msg))
server.receive_data(client_out)
for event in server.events():
pass
server_msg = "0" * max(0, round(rand.gauss(mu, sigma)))
- server_out = server.send(wsproto.events.TextMessage(server_msg))
+ server_out = server.send(wsproto.events.TextMessage(data=server_msg))
client.receive_data(server_out)
for event in client.events():
pass
end = time.perf_counter()
-print(f"{end - start:.4f}s")
+dt = end - start
+print(f"{dt:.3f}s elapsed, {dt/iterations * 1e6:.0f}usec per iteration")
I'm not sure what a possible solution is here, I don't think wsaccel is an option.
Has anyone done performance profiling on wsproto?
As wsaccel is no longer maintained (regression came from switching away) I think there is no clear solution to reverse this. However, I'm now testing a mypyc compiled wsproto that could provide a solution.