#!/bin/python3 # This script is used to measure Rust compilation speed. # It takes a SQL program and first measures the time it takes to compile the whole # program from scratch. It then splits the SQL code into individual # queries and adds them to the program one by one, measuring # the time it takes to re-compile the program. # NOTE: The script doesn't do proper SQL parsing, but simply splits the program # into semicolon-delimited chunks. Make sure there are no semicolons in # comments or inside queries. import argparse import os import time import requests # File locations SCRIPT_DIR = os.path.join(os.path.dirname(__file__)) api_url = "" def main(): parser = argparse.ArgumentParser() parser.add_argument("--sql-program", required=True, help="SQL program to compile") parser.add_argument( "--api-url", required=True, help="Feldera REST API URL (e.g., http://localhost:8080)", ) parser.add_argument( "--with-bearer-token", required=False, help="Authorization Bearer token" ) args = parser.parse_args() # Feldera REST API URL global api_url api_url = args.api_url print(f"Feldera REST API URL: {api_url}") print(f"SQL program: {args.sql_program}") if args.with_bearer_token is None: headers = {} else: headers = {"authorization": f"Bearer {args.with_bearer_token}"} # Test connectivity by fetching existing programs requests.get(f"{api_url}/v0/programs", headers=headers).raise_for_status() # Create program program_name = "compilation_speed_benchmark" program_sql = open(args.sql_program).read() queries = program_sql.split(";") print(f"Found {len(queries)} SQL fragments") response = requests.delete(f"{api_url}/v0/programs/{program_name}", headers=headers) print("Compiling full program") compile(program_name, program_sql, headers) # Add queries one-by-one program = "" times = [] for i in range(0, len(queries)): print(f"Compiling program with {i + 1} queries") program += queries[i] program += ";" # print(f"program: {program}") elapsed = compile(program_name, program, headers) times.append((i + 1, elapsed)) for row in times: print(f"{row[0]}, {row[1]}") def compile(program_name, program, headers): response = requests.put( f"{api_url}/v0/programs/{program_name}", headers=headers, json={"description": "", "code": program}, ) response.raise_for_status() program_version = response.json()["version"] start = time.time() requests.post( f"{api_url}/v0/programs/{program_name}/compile", headers=headers, json={"version": program_version}, ).raise_for_status() while True: status = requests.get( f"{api_url}/v0/programs/{program_name}", headers=headers ).json()["status"] # print(f"Program status: {status}") if status == "Success": break elif ( status != "Pending" and status != "CompilingRust" and status != "SqlCompiled" and status != "CompilingSql" ): raise RuntimeError(f"Failed program compilation with status {status}") time.sleep(1) elapsed = time.time() - start print(f"Finished in {elapsed}s") return elapsed # Main entry point if __name__ == "__main__": main()