-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
5 changed files
with
144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Benchmarks, to be run by codspeed.io in CI | ||
|
||
Benchmarks are run using `pytest`: `pytest benchmarks/`. | ||
This is unlike normal Twisted tests, that use `trial`. | ||
|
||
## Running benchmarks as part of CI | ||
|
||
In CI, we install `pytest-codspeed` run the benchmarks, using GitHub Actions. | ||
The tests are executed on GitHub VMs and the reports are sent to the codspeed.io cloud. | ||
|
||
Note that as of mid-2024, codspeed.io uses a simulated CPU (Cachegrind) to run tests, so the measures of performance are not suitable for optimizing low-level compiled code. | ||
|
||
## Running benchmarks locally | ||
|
||
You can run benchmarks locally by installing `pytest-benchmark` and then running `pytest benchmarks/`. | ||
Unlike `pytest-codspeed`, the results are specific to your computer, but they're helpful for local before/after comparisons. | ||
And `pytest-codspeed` outputs nothing when run locally, at least at the time of writing (May 2024). | ||
|
||
## Writing benchmarks | ||
|
||
See the [Codspeed documentation](https://docs.codspeed.io/benchmarks/python). | ||
|
||
Note that the `@pytest.mark.benchmark` style of benchmark doesn't work with `pytest-benchmark`, so you should not use it. | ||
Instead, use the `benchmark` pytest fixture (i.e. an argument with that name to the test functions). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Copyright (c) Twisted Matrix Laboratories. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Benchmarks for C{HTTP11ClientProtocol}. | ||
""" | ||
|
||
from twisted.internet.testing import StringTransport | ||
from twisted.web._newclient import HTTP11ClientProtocol, Request | ||
from twisted.web.http_headers import Headers | ||
|
||
RESPONSE = """HTTP/1.1 200 OK | ||
Host: blah | ||
Foo: bar | ||
Gaz: baz | ||
Content-length: 3 | ||
abc""".replace( | ||
"\n", "\r\n" | ||
).encode( | ||
"utf-8" | ||
) | ||
|
||
|
||
def test_http_client_small_response(benchmark): | ||
"""Measure the time to run a simple HTTP 1.1 client request.""" | ||
|
||
def go(): | ||
protocol = HTTP11ClientProtocol() | ||
protocol.makeConnection(StringTransport()) | ||
request = Request( | ||
b"GET", b"/foo/bar", Headers({b"Host": [b"example.com"]}), None | ||
) | ||
response = protocol.request(request) | ||
protocol.dataReceived(RESPONSE) | ||
result = [] | ||
response.addCallback(result.append) | ||
assert result | ||
|
||
benchmark(go) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Copyright (c) Twisted Matrix Laboratories. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Benchmarks for the C{twisted.web} server. | ||
""" | ||
|
||
from twisted.internet.testing import StringTransport | ||
from twisted.web import resource, server | ||
|
||
|
||
class Data(resource.Resource): | ||
""" | ||
This is a static, in-memory resource. | ||
""" | ||
|
||
isLeaf = True | ||
|
||
def getChild(self, name): | ||
return self | ||
|
||
def __init__(self, data, type): | ||
resource.Resource.__init__(self) | ||
self.data = data | ||
self.data_len = b"%d" % (len(self.data),) | ||
self.type = type | ||
|
||
def render_GET(self, request): | ||
request.setHeader(b"content-type", self.type) | ||
request.setHeader(b"content-length", self.data_len) | ||
return self.data | ||
|
||
|
||
def test_http11_server_empty_request(benchmark): | ||
"""Benchmark of handling an bodyless HTTP/1.1 request.""" | ||
data = Data(b"This is a result hello hello" * 4, b"text/plain") | ||
factory = server.Site(data) | ||
|
||
def go(): | ||
transport = StringTransport() | ||
protocol = factory.buildProtocol(None) | ||
protocol.makeConnection(transport) | ||
protocol.dataReceived( | ||
b"""\ | ||
GET / HTTP/1.1 | ||
Host: example.com | ||
User-Agent: XXX | ||
Time: XXXX | ||
Content-Length: 0 | ||
""".replace( | ||
b"\n", b"\r\n" | ||
) | ||
) | ||
assert b"200 OK" in transport.io.getvalue() | ||
|
||
benchmark(go) |
Empty file.