content: #!/usr/bin/env python
  
  import collections
  import pathlib
  import sys
  import time
  import zlib
  
  
  REPEAT = 10
  
  WB, ML = 12, 5  # defaults used as a reference
  WBITS = range(9, 16)
  MEMLEVELS = range(1, 10)
  
  
  def benchmark(data):
      size = collections.defaultdict(dict)
      duration = collections.defaultdict(dict)
  
      for wbits in WBITS:
          for memLevel in MEMLEVELS:
              encoder = zlib.compressobj(wbits=-wbits, memLevel=memLevel)
              encoded = []
  
              print(f"Compressing {REPEAT} times with {wbits=} and {memLevel=}")
  
              t0 = time.perf_counter()
  
              for _ in range(REPEAT):
                  for item in data:
                      # Taken from PerMessageDeflate.encode
                      item = encoder.compress(item) + encoder.flush(zlib.Z_SYNC_FLUSH)
                      if item.endswith(b"\x00\x00\xff\xff"):
                          item = item[:-4]
                      encoded.append(item)
  
              t1 = time.perf_counter()
  
              size[wbits][memLevel] = sum(len(item) for item in encoded) / REPEAT
              duration[wbits][memLevel] = (t1 - t0) / REPEAT
  
      raw_size = sum(len(item) for item in data)
  
      print("=" * 79)
      print("Compression ratio")
      print("=" * 79)
      print("\t".join(["wb \\ ml"] + [str(memLevel) for memLevel in MEMLEVELS]))
      for wbits in WBITS:
          print(
              "\t".join(
                  [str(wbits)]
                  + [
                      f"{100 * (1 - size[wbits][memLevel] / raw_size):.1f}%"
                      for memLevel in MEMLEVELS
                  ]
              )
          )
      print("=" * 79)
      print()
  
      print("=" * 79)
      print("CPU time")
      print("=" * 79)
      print("\t".join(["wb \\ ml"] + [str(memLevel) for memLevel in MEMLEVELS]))
      for wbits in WBITS:
          print(
              "\t".join(
                  [str(wbits)]
                  + [
                      f"{1000 * duration[wbits][memLevel]:.1f}ms"
                      for memLevel in MEMLEVELS
                  ]
              )
          )
      print("=" * 79)
      print()
  
      print("=" * 79)
      print(f"Size vs. {WB} \\ {ML}")
      print("=" * 79)
      print("\t".join(["wb \\ ml"] + [str(memLevel) for memLevel in MEMLEVELS]))
      for wbits in WBITS:
          print(
              "\t".join(
                  [str(wbits)]
                  + [
                      f"{100 * (size[wbits][memLevel] / size[WB][ML] - 1):.1f}%"
                      for memLevel in MEMLEVELS
                  ]
              )
          )
      print("=" * 79)
      print()
  
      print("=" * 79)
      print(f"Time vs. {WB} \\ {ML}")
      print("=" * 79)
      print("\t".join(["wb \\ ml"] + [str(memLevel) for memLevel in MEMLEVELS]))
      for wbits in WBITS:
          print(
              "\t".join(
                  [str(wbits)]
                  + [
                      f"{100 * (duration[wbits][memLevel] / duration[WB][ML] - 1):.1f}%"
                      for memLevel in MEMLEVELS
                  ]
              )
          )
      print("=" * 79)
      print()
  
  
  def main(corpus):
      data = [file.read_bytes() for file in corpus.iterdir()]
      benchmark(data)
  
  
  if __name__ == "__main__":
      if len(sys.argv) < 2:
          print(f"Usage: {sys.argv[0]} [directory]")
          sys.exit(2)
      main(pathlib.Path(sys.argv[1]))
  