#!/usr/bin/env python """ An example of benchmarking cache write speeds with semi-randomized response content Usage (optionally for a specific backend and/or serializer): ``` python benchmark.py -b -s ``` """ from argparse import ArgumentParser from os import urandom from random import random from time import perf_counter as time import requests from rich import print from rich.progress import Progress from requests_cache import CachedResponse, CachedSession BASE_RESPONSE = requests.get('https://httpbin.org/get') CACHE_NAME = 'rubbish_bin' WARMUP_ITERATIONS = 100 ITERATIONS = 5000 MAX_RESPONSE_SIZE = 1024 * 350 # Defaults for DynamoDB AWS_OPTIONS = { 'endpoint_url': 'http://localhost:8000', 'region_name': 'us-east-1', 'aws_access_key_id': 'placeholder', 'aws_secret_access_key': 'placeholder', } def test_write_speed(session, max_size): for i in range(WARMUP_ITERATIONS): new_response = get_randomized_response(i, max_size) session.cache.save_response(new_response) with Progress() as progress: task = progress.add_task('[cyan]Testing write speed...', total=ITERATIONS) start = time() for i in range(ITERATIONS): new_response = get_randomized_response(i, max_size) session.cache.save_response(new_response) progress.update(task, advance=1) elapsed = time() - start avg = (elapsed / ITERATIONS) * 1000 print(f'[cyan]Elapsed: [green]{elapsed:.3f}[/] seconds (avg [green]{avg:.3f}[/] ms per write)') def test_read_speed(session): keys = list(session.cache.responses.keys()) for i in range(WARMUP_ITERATIONS): key = keys[i % len(keys)] session.cache.get_response(key) with Progress() as progress: task = progress.add_task('[cyan]Testing read speed...', total=ITERATIONS) start = time() for i in range(ITERATIONS): key = keys[i % len(keys)] session.cache.get_response(key) progress.update(task, advance=1) elapsed = time() - start avg = (elapsed / ITERATIONS) * 1000 print(f'[cyan]Elapsed: [green]{elapsed:.3f}[/] seconds (avg [green]{avg:.3f}[/] ms per read)') def get_randomized_response(i=0, max_size=MAX_RESPONSE_SIZE): """Get a response with randomized content""" new_response = CachedResponse.from_response(BASE_RESPONSE) n_bytes = int(random() * max_size) new_response._content = urandom(n_bytes) new_response.request.url += f'/response_{i}' return new_response if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('-b', '--backend', default='sqlite') parser.add_argument('-s', '--serializer', default='pickle') parser.add_argument('-m', '--max-size', default=MAX_RESPONSE_SIZE, type=float) args = parser.parse_args() print(f'[cyan]Benchmarking {args.backend} backend with {args.serializer} serializer') kwargs = {} if args.backend == 'dynamodb': kwargs = AWS_OPTIONS elif args.backend == 'sqlite-memory': args.backend = 'sqlite' kwargs = {'use_memory': True} session = CachedSession( CACHE_NAME, backend=args.backend, serializer=args.serializer, **kwargs, ) test_write_speed(session, args.max_size) test_read_speed(session)