Skip to content

Commit

Permalink
Add benchmarking utility
Browse files Browse the repository at this point in the history
This will be useful for when wanting to run small benchmarks. It will
also allow us to remove a small snippet of code we previously had in the
tests.

Signed-off-by: Rodrigo Tobar <rtobar@icrar.org>
  • Loading branch information
rtobar committed Aug 23, 2024
1 parent d1a5a59 commit 20fe518
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
declaring that our C extension doesn't need the GIL.
In free-threaded builds the `gil_release_mode` parameter doesn't have any effect.
* Added `CRC32CHash.checksum` auxiliary property.
* Added new ``crc32c.benchmark`` utility for simple benchmarking.
* The ``crc32c`` module doesn't fail to import when ``CRC32C_SW_MODE`` is ``none``
and no hardware acceleration is found,
making the act of importing the module less ackward.
Expand Down
4 changes: 4 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ the following module-level values:
is software- or hardware-based.
* ``big_endian`` indicates whether the platform is big endian or not.

A benchmarking utility can be found
when executing the ``crc32c.benchmark`` module.
Consult its help with the ``-h`` flag for options.

Implementation details
----------------------

Expand Down
44 changes: 44 additions & 0 deletions src/crc32c/benchmark.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import argparse
import time

from ._crc32c import crc32c

DEFAULT_SIZE = 100 * 1024 * 1024
DEFAULT_ITERATIONS = 10


def run(size: int, iterations: int) -> float:
data = b" " * size
start = time.monotonic()
[crc32c(data) for _ in range(iterations)]
end = time.monotonic()
return end - start


def main() -> None:

parser = argparse.ArgumentParser()
parser.add_argument(
"-s",
"--size",
type=int,
help=f"Amount of bytes to checksum, defaults to {DEFAULT_SIZE}",
default=DEFAULT_SIZE,
)
parser.add_argument(
"-i",
"--iterations",
type=int,
help=f"Number of times the checksum should we run over the data, defaults to {DEFAULT_ITERATIONS}",
default=DEFAULT_ITERATIONS,
)

options = parser.parse_args()
duration = run(options.size, options.iterations)
print(
f"crc32c ran at {options.size * options.iterations / duration / 1024 / 1024 / 1024:.3f} [GB/s]"
)


if __name__ == "__main__":
main()
10 changes: 10 additions & 0 deletions test/test_benchmark.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import subprocess
import sys

import pytest


@pytest.mark.calculates_crc32c
def test_benchmark() -> None:
out = subprocess.check_output([sys.executable, "-m", "crc32c.benchmark"])
assert b"crc32c ran at" in out

0 comments on commit 20fe518

Please sign in to comment.