From cc3543214496feaee0391aa99a28efaf1092b9ce Mon Sep 17 00:00:00 2001 From: vikingmew Date: Fri, 4 Sep 2026 13:21:23 +0000 Subject: [PATCH] bench: compare QuickPython with CPython --- benchmarks/talk_comparison/README.md | 26 ++ .../fixtures/medium_response.json | 93 +++++++ benchmarks/talk_comparison/raw-results.json | 213 +++++++++++++++ benchmarks/talk_comparison/results.md | 51 ++++ benchmarks/talk_comparison/run.py | 251 ++++++++++++++++++ .../talk_comparison/workloads/cold_start.py | 1 + .../talk_comparison/workloads/compute_loop.py | 6 + .../talk_comparison/workloads/dict_ops.py | 6 + .../workloads/json_dumps.py.tmpl | 7 + .../workloads/json_loads.py.tmpl | 6 + .../talk_comparison/workloads/string_join.py | 4 + 11 files changed, 664 insertions(+) create mode 100644 benchmarks/talk_comparison/README.md create mode 100644 benchmarks/talk_comparison/fixtures/medium_response.json create mode 100644 benchmarks/talk_comparison/raw-results.json create mode 100644 benchmarks/talk_comparison/results.md create mode 100644 benchmarks/talk_comparison/run.py create mode 100644 benchmarks/talk_comparison/workloads/cold_start.py create mode 100644 benchmarks/talk_comparison/workloads/compute_loop.py create mode 100644 benchmarks/talk_comparison/workloads/dict_ops.py create mode 100644 benchmarks/talk_comparison/workloads/json_dumps.py.tmpl create mode 100644 benchmarks/talk_comparison/workloads/json_loads.py.tmpl create mode 100644 benchmarks/talk_comparison/workloads/string_join.py diff --git a/benchmarks/talk_comparison/README.md b/benchmarks/talk_comparison/README.md new file mode 100644 index 0000000..5e92e90 --- /dev/null +++ b/benchmarks/talk_comparison/README.md @@ -0,0 +1,26 @@ +# QuickPython vs CPython talk benchmark + +This is the one-off, process-level benchmark used for QPY-83. It is separate +from the long-term suite proposed in `spec/benchmarks.md`. + +The harness builds QuickPython once in release mode, generates each workload +from the committed templates and fixture, and then invokes the resulting +binary directly. CPython and QuickPython receive the exact same generated +source file. Non-cold workloads run three times and report the minimum +wall-clock time divided by the fixed iteration count. Cold start uses twenty +fresh processes and reports minimum and average wall-clock time. + +From the repository root, run: + +```sh +python3 benchmarks/talk_comparison/run.py +``` + +The default output files are `raw-results.json` and `results.md` in this +directory. A single workload process is limited to five minutes by default; +use `--timeout SECONDS` to change that. A timeout or unsupported operation is +reported as a failure, never as a timing result. The harness does not invoke a +container engine. + +The checked-in result files are a snapshot from the machine described in +`results.md`. Re-running replaces them with a new same-machine comparison. diff --git a/benchmarks/talk_comparison/fixtures/medium_response.json b/benchmarks/talk_comparison/fixtures/medium_response.json new file mode 100644 index 0000000..305be80 --- /dev/null +++ b/benchmarks/talk_comparison/fixtures/medium_response.json @@ -0,0 +1,93 @@ +{ + "person": { + "id": "d50887ca-a6ce-4e59-b89f-14f0b5d03b03", + "name": { + "fullName": "Leonid Bugaev", + "givenName": "Leonid", + "familyName": "Bugaev" + }, + "email": "leonsbox@gmail.com", + "gender": "male", + "location": "Saint Petersburg, Saint Petersburg, RU", + "geo": { + "city": "Saint Petersburg", + "state": "Saint Petersburg", + "country": "Russia", + "lat": 59.9342802, + "lng": 30.3350986 + }, + "bio": "Senior engineer at Granify.com", + "site": "http://flickfaver.com", + "avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/d50887ca-a6ce-4e59-b89f-14f0b5d03b03", + "employment": { + "name": "www.latera.ru", + "title": "Software Engineer", + "domain": "gmail.com" + }, + "facebook": { + "handle": "leonid.bugaev" + }, + "github": { + "handle": "buger", + "id": 14009, + "avatar": "https://avatars.githubusercontent.com/u/14009?v=3", + "company": "Granify", + "blog": "http://leonsbox.com", + "followers": 95, + "following": 10 + }, + "twitter": { + "handle": "flickfaver", + "id": 77004410, + "bio": null, + "followers": 2, + "following": 1, + "statuses": 5, + "favorites": 0, + "location": "", + "site": "http://flickfaver.com", + "avatar": null + }, + "linkedin": { + "handle": "in/leonidbugaev" + }, + "googleplus": { + "handle": null + }, + "angellist": { + "handle": "leonid-bugaev", + "id": 61541, + "bio": "Senior engineer at Granify.com", + "blog": "http://buger.github.com", + "site": "http://buger.github.com", + "followers": 41, + "avatar": "https://d1qb2nb5cznatu.cloudfront.net/users/61541-medium_jpg?1405474390" + }, + "klout": { + "handle": null, + "score": null + }, + "foursquare": { + "handle": null + }, + "aboutme": { + "handle": "leonid.bugaev", + "bio": null, + "avatar": null + }, + "gravatar": { + "handle": "buger", + "urls": [ + ], + "avatar": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510", + "avatars": [ + { + "url": "http://1.gravatar.com/avatar/f7c8edd577d13b8930d5522f28123510", + "type": "thumbnail" + } + ] + }, + "fuzzy": false + }, + "company": null +} diff --git a/benchmarks/talk_comparison/raw-results.json b/benchmarks/talk_comparison/raw-results.json new file mode 100644 index 0000000..df18284 --- /dev/null +++ b/benchmarks/talk_comparison/raw-results.json @@ -0,0 +1,213 @@ +{ + "schema_version": 1, + "environment": { + "os_arch": "Linux-7.0.11-orbstack-00354-gde2ab3f9e944-aarch64-with-glibc2.41", + "cpu": "unavailable", + "quickpython_commit": "a8168c3432111fd341c581ffacb798351054650f", + "rustc": "rustc 1.98.1 (48a229cea 2026-09-01)", + "cargo": "cargo 1.98.1 (797e8a9bc 2026-08-05)", + "cpython": "Python 3.11.16" + }, + "commands": [ + "cargo build --release", + "target/release/quickpython run ", + "python3 " + ], + "measurement": { + "non_cold_runs": 3, + "cold_runs": 20, + "timeout_seconds": 300.0, + "clock": "time.perf_counter_ns" + }, + "results": { + "quickpython": { + "cold_start": { + "status": "success", + "samples_seconds": [ + 0.002484589, + 0.000816751, + 0.002415254, + 0.000524543, + 0.002312463, + 0.002449422, + 0.002501796, + 0.000497917, + 0.002567713, + 0.00213592, + 0.001992963, + 0.002017962, + 0.000503543, + 0.002374129, + 0.002101588, + 0.000490793, + 0.002319255, + 0.002184629, + 0.000510917, + 0.002370921 + ], + "min_ms": 0.490793, + "avg_ms": 1.7786534, + "checksum": "2" + }, + "json_loads": { + "status": "success", + "iterations": 200000, + "samples_seconds": [ + 3.180023342, + 3.335013011, + 3.26884951 + ], + "min_us_per_iter": 15.90011671, + "checksum": "d50887ca-a6ce-4e59-b89f-14f0b5d03b03" + }, + "json_dumps": { + "status": "failed", + "iterations": 200000, + "stage": "runtime", + "category": "semantic difference", + "error": "expected stdout '1815', got '1685'", + "samples": [ + { + "elapsed_seconds": 1.184112877, + "returncode": 0, + "stdout": "1685\n", + "stderr": "", + "timed_out": false + }, + { + "elapsed_seconds": 1.216834148, + "returncode": 0, + "stdout": "1685\n", + "stderr": "", + "timed_out": false + }, + { + "elapsed_seconds": 1.24416445, + "returncode": 0, + "stdout": "1685\n", + "stderr": "", + "timed_out": false + } + ] + }, + "compute_loop": { + "status": "success", + "iterations": 20000, + "samples_seconds": [ + 1.311903371, + 1.300991475, + 1.202045287 + ], + "min_us_per_iter": 60.10226435, + "checksum": "2646700" + }, + "string_join": { + "status": "success", + "iterations": 200000, + "samples_seconds": [ + 0.104971033, + 0.102914071, + 0.103065405 + ], + "min_us_per_iter": 0.514570355, + "checksum": "alpha,beta,gamma,delta" + }, + "dict_ops": { + "status": "success", + "iterations": 50000, + "samples_seconds": [ + 0.840918225, + 0.82496832, + 0.883600098 + ], + "min_us_per_iter": 16.4993664, + "checksum": "2401" + } + }, + "cpython": { + "cold_start": { + "status": "success", + "samples_seconds": [ + 0.009372643, + 0.007881515, + 0.007195638, + 0.006868554, + 0.006970639, + 0.006985347, + 0.007123222, + 0.006893013, + 0.006987305, + 0.006018803, + 0.006011012, + 0.008965017, + 0.005422052, + 0.006649429, + 0.007071013, + 0.006883305, + 0.005946678, + 0.007103806, + 0.006899805, + 0.006989389 + ], + "min_ms": 5.422052, + "avg_ms": 7.011909250000001, + "checksum": "2" + }, + "json_loads": { + "status": "success", + "iterations": 200000, + "samples_seconds": [ + 1.208114381, + 1.169858476, + 1.25310555 + ], + "min_us_per_iter": 5.8492923800000005, + "checksum": "d50887ca-a6ce-4e59-b89f-14f0b5d03b03" + }, + "json_dumps": { + "status": "success", + "iterations": 200000, + "samples_seconds": [ + 1.721984775, + 1.671889139, + 1.695675017 + ], + "min_us_per_iter": 8.359445695, + "checksum": "1815" + }, + "compute_loop": { + "status": "success", + "iterations": 20000, + "samples_seconds": [ + 0.152286289, + 0.176022168, + 0.21998496 + ], + "min_us_per_iter": 7.614314449999999, + "checksum": "2646700" + }, + "string_join": { + "status": "success", + "iterations": 200000, + "samples_seconds": [ + 0.021954375, + 0.020200205, + 0.02095654 + ], + "min_us_per_iter": 0.101001025, + "checksum": "alpha,beta,gamma,delta" + }, + "dict_ops": { + "status": "success", + "iterations": 50000, + "samples_seconds": [ + 0.125769906, + 0.111035836, + 0.110017335 + ], + "min_us_per_iter": 2.2003467, + "checksum": "2401" + } + } + } +} diff --git a/benchmarks/talk_comparison/results.md b/benchmarks/talk_comparison/results.md new file mode 100644 index 0000000..7295dfe --- /dev/null +++ b/benchmarks/talk_comparison/results.md @@ -0,0 +1,51 @@ +# QuickPython vs CPython benchmark results + +## Environment + +- os_arch: `Linux-7.0.11-orbstack-00354-gde2ab3f9e944-aarch64-with-glibc2.41` +- cpu: `unavailable` +- quickpython_commit: `a8168c3432111fd341c581ffacb798351054650f` +- rustc: `rustc 1.98.1 (48a229cea 2026-09-01)` +- cargo: `cargo 1.98.1 (797e8a9bc 2026-08-05)` +- cpython: `Python 3.11.16` + +## Commands + +- `cargo build --release` +- `target/release/quickpython run ` +- `python3 ` + +## Comparison + +| workload | N | QuickPython | CPython | QPY/CPython | status / notes | +|---|---:|---:|---:|---:|---| +| cold_start | 20 | 0.491/1.779 ms min/avg | 5.422/7.012 ms min/avg | 0.09x | success; checksum verified | +| json_loads | 200000 | 15.900 µs/iter | 5.849 µs/iter | 2.72x | success; checksum verified | +| json_dumps | 200000 | failed | success | — | runtime; semantic difference: expected stdout '1815', got '1685' | +| compute_loop | 20000 | 60.102 µs/iter | 7.614 µs/iter | 7.89x | success; checksum verified | +| string_join | 200000 | 0.515 µs/iter | 0.101 µs/iter | 5.09x | success; checksum verified | +| dict_ops | 50000 | 16.499 µs/iter | 2.200 µs/iter | 7.50x | success; checksum verified | + +## Raw elapsed samples + +### quickpython + +- cold_start: `0.002, 0.001, 0.002, 0.001, 0.002, 0.002, 0.003, 0.000, 0.003, 0.002, 0.002, 0.002, 0.001, 0.002, 0.002, 0.000, 0.002, 0.002, 0.001, 0.002` seconds +- json_loads: `3.180, 3.335, 3.269` seconds +- json_dumps: failed at runtime (semantic difference): expected stdout '1815', got '1685' +- compute_loop: `1.312, 1.301, 1.202` seconds +- string_join: `0.105, 0.103, 0.103` seconds +- dict_ops: `0.841, 0.825, 0.884` seconds + +### cpython + +- cold_start: `0.009, 0.008, 0.007, 0.007, 0.007, 0.007, 0.007, 0.007, 0.007, 0.006, 0.006, 0.009, 0.005, 0.007, 0.007, 0.007, 0.006, 0.007, 0.007, 0.007` seconds +- json_loads: `1.208, 1.170, 1.253` seconds +- json_dumps: `1.722, 1.672, 1.696` seconds +- compute_loop: `0.152, 0.176, 0.220` seconds +- string_join: `0.022, 0.020, 0.021` seconds +- dict_ops: `0.126, 0.111, 0.110` seconds + +## Conclusion + +This same-machine snapshot supports comparisons only for the successful workloads (cold_start, json_loads, compute_loop, string_join, dict_ops). For short-lived agent calls, cold-start results include process startup plus parsing, compilation, and execution, while non-cold results amortize those costs over the fixed in-runtime loop. Unavailable workloads (json_dumps) are compatibility findings and provide no evidence about their relative performance. diff --git a/benchmarks/talk_comparison/run.py b/benchmarks/talk_comparison/run.py new file mode 100644 index 0000000..b2ff5f6 --- /dev/null +++ b/benchmarks/talk_comparison/run.py @@ -0,0 +1,251 @@ +#!/usr/bin/env python3 +"""Collect the QPY-83 same-source, process-level benchmark snapshot.""" + +from __future__ import annotations + +import argparse +import json +import os +import platform +import statistics +import subprocess +import tempfile +import time +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[2] +HERE = Path(__file__).resolve().parent +WORKLOADS = HERE / "workloads" +FIXTURE = HERE / "fixtures" / "medium_response.json" +QPY = ROOT / "target" / "release" / "quickpython" +RUNS = 3 +COLD_RUNS = 20 +SPECS = { + "json_loads": (200_000, "d50887ca-a6ce-4e59-b89f-14f0b5d03b03"), + "json_dumps": (200_000, "1815"), + "compute_loop": (20_000, "2646700"), + "string_join": (200_000, "alpha,beta,gamma,delta"), + "dict_ops": (50_000, "2401"), +} + + +def command_output(command: list[str]) -> str: + return subprocess.run(command, cwd=ROOT, check=True, text=True, + capture_output=True).stdout.strip() + + +def cpu_description() -> str: + description = platform.processor() + cpuinfo = Path("/proc/cpuinfo") + if not description and cpuinfo.is_file(): + for line in cpuinfo.read_text(encoding="utf-8").splitlines(): + if line.lower().startswith(("model name", "hardware", "processor")): + value = line.partition(":")[2].strip() + if value and not value.isdigit(): + return value + return description or "unavailable" + + +def prepare_sources(directory: Path) -> dict[str, Path]: + sources = {"cold_start": WORKLOADS / "cold_start.py"} + data_literal = repr(FIXTURE.read_text(encoding="utf-8")) + for name in SPECS: + plain = WORKLOADS / f"{name}.py" + if plain.exists(): + sources[name] = plain + else: + rendered = (WORKLOADS / f"{name}.py.tmpl").read_text( + encoding="utf-8").replace("__DATA__", data_literal) + destination = directory / f"{name}.py" + destination.write_text(rendered, encoding="utf-8") + sources[name] = destination + return sources + + +def invoke(command: list[str], timeout: float) -> dict[str, Any]: + start = time.perf_counter_ns() + try: + process = subprocess.run(command, cwd=ROOT, text=True, + capture_output=True, timeout=timeout) + except subprocess.TimeoutExpired as error: + return {"elapsed_seconds": (time.perf_counter_ns() - start) / 1e9, + "returncode": None, "stdout": error.stdout or "", + "stderr": error.stderr or "", "timed_out": True} + return {"elapsed_seconds": (time.perf_counter_ns() - start) / 1e9, + "returncode": process.returncode, "stdout": process.stdout, + "stderr": process.stderr, "timed_out": False} + + +def classify(sample: dict[str, Any]) -> dict[str, str]: + message = str(sample.get("stderr") or sample.get("stdout") or "").strip() + lowered = message.lower() + if sample["timed_out"]: + return {"stage": "timeout", "category": "environment issue", + "error": "process exceeded configured timeout"} + if "parse" in lowered or "syntax" in lowered: + stage, category = "parse", "unsupported syntax" + elif "compile" in lowered or "not implemented" in lowered: + stage, category = "compile", "unsupported syntax" + elif "not found" in lowered or "has no attribute" in lowered or "unknown method" in lowered: + stage, category = "runtime", "missing builtin/method" + else: + stage, category = "runtime", "other" + return {"stage": stage, "category": category, + "error": " ".join(message.split())[:300] or "non-zero exit"} + + +def validate(sample: dict[str, Any], expected: str) -> str | None: + if sample["timed_out"] or sample["returncode"] != 0: + return None + lines = str(sample["stdout"]).strip().splitlines() + return expected if lines == [expected] else None + + +def measure_runtime(command_prefix: list[str], sources: dict[str, Path], + timeout: float) -> dict[str, Any]: + result: dict[str, Any] = {} + cold_samples = [invoke(command_prefix + [str(sources["cold_start"])], timeout) + for _ in range(COLD_RUNS)] + if all(validate(sample, "2") for sample in cold_samples): + elapsed = [sample["elapsed_seconds"] for sample in cold_samples] + result["cold_start"] = { + "status": "success", "samples_seconds": elapsed, + "min_ms": min(elapsed) * 1000, + "avg_ms": statistics.fmean(elapsed) * 1000, + "checksum": "2", + } + else: + failed = next(sample for sample in cold_samples if not validate(sample, "2")) + result["cold_start"] = {"status": "failed", **classify(failed), + "samples": cold_samples} + + for name, (iterations, expected) in SPECS.items(): + samples = [invoke(command_prefix + [str(sources[name])], timeout) + for _ in range(RUNS)] + if all(validate(sample, expected) for sample in samples): + elapsed = [sample["elapsed_seconds"] for sample in samples] + result[name] = { + "status": "success", "iterations": iterations, + "samples_seconds": elapsed, + "min_us_per_iter": min(elapsed) * 1_000_000 / iterations, + "checksum": expected, + } + else: + failed = next(sample for sample in samples if not validate(sample, expected)) + detail = classify(failed) if failed["returncode"] != 0 or failed["timed_out"] else { + "stage": "runtime", "category": "semantic difference", + "error": f"expected stdout {expected!r}, got {failed['stdout'].strip()!r}", + } + result[name] = {"status": "failed", "iterations": iterations, + **detail, "samples": samples} + return result + + +def fmt(value: float) -> str: + return f"{value:.3f}" + + +def render_markdown(data: dict[str, Any]) -> str: + qpy, cpython = data["results"]["quickpython"], data["results"]["cpython"] + lines = [ + "# QuickPython vs CPython benchmark results", "", + "## Environment", "", + ] + for key, value in data["environment"].items(): + lines.append(f"- {key}: `{value}`") + lines += ["", "## Commands", ""] + lines += [f"- `{command}`" for command in data["commands"]] + lines += ["", "## Comparison", "", + "| workload | N | QuickPython | CPython | QPY/CPython | status / notes |", + "|---|---:|---:|---:|---:|---|"] + for name in ["cold_start", *SPECS]: + qr, cr = qpy[name], cpython[name] + n = COLD_RUNS if name == "cold_start" else SPECS[name][0] + if qr["status"] == cr["status"] == "success": + if name == "cold_start": + qtext = f"{fmt(qr['min_ms'])}/{fmt(qr['avg_ms'])} ms min/avg" + ctext = f"{fmt(cr['min_ms'])}/{fmt(cr['avg_ms'])} ms min/avg" + ratio = qr["min_ms"] / cr["min_ms"] + else: + qtext = f"{fmt(qr['min_us_per_iter'])} µs/iter" + ctext = f"{fmt(cr['min_us_per_iter'])} µs/iter" + ratio = qr["min_us_per_iter"] / cr["min_us_per_iter"] + note = "success; checksum verified" + ratio_text = f"{ratio:.2f}x" + else: + qtext = "failed" if qr["status"] != "success" else "success" + ctext = "failed" if cr["status"] != "success" else "success" + ratio_text = "—" + failed = qr if qr["status"] != "success" else cr + note = f"{failed['stage']}; {failed['category']}: {failed['error']}" + lines.append(f"| {name} | {n} | {qtext} | {ctext} | {ratio_text} | {note} |") + lines += ["", "## Raw elapsed samples", ""] + for runtime, runtime_results in data["results"].items(): + lines += [f"### {runtime}", ""] + for name, item in runtime_results.items(): + if item["status"] == "success": + samples = ", ".join(fmt(x) for x in item["samples_seconds"]) + lines.append(f"- {name}: `{samples}` seconds") + else: + lines.append(f"- {name}: failed at {item['stage']} ({item['category']}): " + f"{item['error']}") + lines.append("") + successful = [name for name in ["cold_start", *SPECS] + if qpy[name]["status"] == cpython[name]["status"] == "success"] + failed = [name for name in ["cold_start", *SPECS] if name not in successful] + lines += ["## Conclusion", "", + "This same-machine snapshot supports comparisons only for the successful " + f"workloads ({', '.join(successful) or 'none'}). For short-lived agent calls, " + "cold-start results include process startup plus parsing, compilation, and execution, " + "while non-cold results amortize those costs over the fixed in-runtime loop. " + f"Unavailable workloads ({', '.join(failed) or 'none'}) are compatibility findings " + "and provide no evidence about their relative performance.", ""] + return "\n".join(lines) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--timeout", type=float, default=300.0) + parser.add_argument("--json-output", type=Path, default=HERE / "raw-results.json") + parser.add_argument("--markdown-output", type=Path, default=HERE / "results.md") + args = parser.parse_args() + + # This is the only build. Every timed invocation below calls QPY directly. + subprocess.run(["cargo", "build", "--release"], cwd=ROOT, check=True) + if not QPY.is_file(): + raise SystemExit(f"release binary not found: {QPY}") + + with tempfile.TemporaryDirectory(prefix="qpy-83-") as temporary: + sources = prepare_sources(Path(temporary)) + environment = { + "os_arch": platform.platform(), + "cpu": cpu_description(), + "quickpython_commit": command_output(["git", "rev-parse", "HEAD"]), + "rustc": command_output(["rustc", "--version"]), + "cargo": command_output(["cargo", "--version"]), + "cpython": command_output(["python3", "--version"]), + } + data = { + "schema_version": 1, + "environment": environment, + "commands": [ + "cargo build --release", + "target/release/quickpython run ", + "python3 ", + ], + "measurement": {"non_cold_runs": RUNS, "cold_runs": COLD_RUNS, + "timeout_seconds": args.timeout, + "clock": "time.perf_counter_ns"}, + "results": { + "quickpython": measure_runtime([str(QPY), "run"], sources, args.timeout), + "cpython": measure_runtime(["python3"], sources, args.timeout), + }, + } + args.json_output.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8") + args.markdown_output.write_text(render_markdown(data), encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/benchmarks/talk_comparison/workloads/cold_start.py b/benchmarks/talk_comparison/workloads/cold_start.py new file mode 100644 index 0000000..904fa0d --- /dev/null +++ b/benchmarks/talk_comparison/workloads/cold_start.py @@ -0,0 +1 @@ +print(1 + 1) diff --git a/benchmarks/talk_comparison/workloads/compute_loop.py b/benchmarks/talk_comparison/workloads/compute_loop.py new file mode 100644 index 0000000..a87cabc --- /dev/null +++ b/benchmarks/talk_comparison/workloads/compute_loop.py @@ -0,0 +1,6 @@ +N = 20000 +for i in range(N): + s = 0 + for j in range(200): + s += j * j +print(s) diff --git a/benchmarks/talk_comparison/workloads/dict_ops.py b/benchmarks/talk_comparison/workloads/dict_ops.py new file mode 100644 index 0000000..dc2c74e --- /dev/null +++ b/benchmarks/talk_comparison/workloads/dict_ops.py @@ -0,0 +1,6 @@ +N = 50000 +for i in range(N): + d = {} + for j in range(50): + d[j] = j * j +print(d[49]) diff --git a/benchmarks/talk_comparison/workloads/json_dumps.py.tmpl b/benchmarks/talk_comparison/workloads/json_dumps.py.tmpl new file mode 100644 index 0000000..534a6fa --- /dev/null +++ b/benchmarks/talk_comparison/workloads/json_dumps.py.tmpl @@ -0,0 +1,7 @@ +import json +DATA = __DATA__ +OBJ = json.loads(DATA) +N = 200000 +for i in range(N): + result = json.dumps(OBJ) +print(len(result)) diff --git a/benchmarks/talk_comparison/workloads/json_loads.py.tmpl b/benchmarks/talk_comparison/workloads/json_loads.py.tmpl new file mode 100644 index 0000000..9f6c21a --- /dev/null +++ b/benchmarks/talk_comparison/workloads/json_loads.py.tmpl @@ -0,0 +1,6 @@ +import json +DATA = __DATA__ +N = 200000 +for i in range(N): + result = json.loads(DATA) +print(result['person']['id']) diff --git a/benchmarks/talk_comparison/workloads/string_join.py b/benchmarks/talk_comparison/workloads/string_join.py new file mode 100644 index 0000000..a1ac9c1 --- /dev/null +++ b/benchmarks/talk_comparison/workloads/string_join.py @@ -0,0 +1,4 @@ +N = 200000 +for i in range(N): + result = ','.join(['alpha', 'beta', 'gamma', 'delta']) +print(result)