Path: blob/master/benchmark/benchmark_stream.py
641 views
import argparse1import math2from collections import OrderedDict3from concurrent.futures import ThreadPoolExecutor4from functools import partial5from timeit import default_timer67import requests8from psutil import cpu_percent, process_iter91011def parse_arguments():12parser = argparse.ArgumentParser(description="Benchmark Stream.")13parser.add_argument(14"--stream-url",15help="Url to Stream App For example, http://localhost:80",16default="http://localhost:80",17)18parser.add_argument("--video", default="assets/cars.mp4")19parser.add_argument("--iterations", default=5, type=int)20return parser.parse_args()212223def print_table(results):24if not results:25return26print("| Speed | l_min | l_max |")27print("| ------- | ------ | ------ |")28for result in results:29print("| {avg:7.1f} | {min:6.1f} | {max:6.1f} |".format(**result))303132def stream_api(fp, stream_url, exit_on_error=True):33fp.seek(0)34response = requests.post(stream_url, files=dict(upload=fp))35if response is None:36return {}37if response.status_code < 200 or response.status_code > 300:38print(response.text)39if exit_on_error:40exit(1)41return response.json(object_pairs_hook=OrderedDict)424344def call_duration(path, stream_url):45now = default_timer()46with open(path, "rb") as fp:47stream_api(fp, stream_url=stream_url)48return (default_timer() - now) * 1000495051def benchmark(args, executor):52now = default_timer()53stats = list(54executor.map(55partial(call_duration, stream_url=args.stream_url),56[args.video] * args.iterations,57)58)59duration = (default_timer() - now) * 100060yield dict(min=min(stats), max=max(stats), avg=duration / args.iterations)616263def mem_usage():64usage = {}65for process in process_iter():66if "main.py" in process.cmdline() or "start.sh" in process.cmdline():67usage[process.pid] = process.memory_info()68return usage697071def convert_size(size_bytes):72if size_bytes == 0:73return "0B"74sign = ""75if size_bytes < 0:76size_bytes *= -177sign = "-"78size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")79i = int(math.floor(math.log(size_bytes, 1024)))80p = math.pow(1024, i)81s = round(size_bytes / p, 2)82return f"{sign}{s} {size_name[i]}"838485def main():86args = parse_arguments()87initial_mem = mem_usage()88cpu_percent() # first time this is called it will return a meaningless 0.089with ThreadPoolExecutor(max_workers=1) as executor:90# Warmup91list(92executor.map(93partial(call_duration, stream_url=args.stream_url), [args.video]94)95)96# Benchmark97results = list(benchmark(args, executor))9899# Memory Usage100print(f"CPU: {cpu_percent()}%")101for pid, mem in mem_usage().items():102print(103f"PID: {pid:5}, "104f"RES {convert_size(mem.rss):10} ({convert_size(mem.rss - initial_mem[pid].rss):10}), "105f"SHR {convert_size(mem.shared):10} ({convert_size(mem.shared - initial_mem[pid].shared):10})"106)107print_table(results)108109110if __name__ == "__main__":111main()112113114