pyodide/benchmark/benchmark.py

139 lines
4.0 KiB
Python
Raw Normal View History

2018-04-05 22:07:33 +00:00
import json
2018-08-03 16:48:22 +00:00
from pathlib import Path
2018-04-05 22:07:33 +00:00
import re
import subprocess
import sys
from time import time
2018-04-05 22:07:33 +00:00
sys.path.insert(0, str((Path(__file__).resolve().parents[1] / "test")))
sys.path.insert(0, str((Path(__file__).resolve().parents[1])))
2018-08-03 16:48:22 +00:00
import conftest # noqa: E402
2018-04-05 22:07:33 +00:00
SKIP = set(["fft", "hyantes", "README"])
2018-04-05 22:07:33 +00:00
def print_entry(name, res):
print(" - ", name)
print(" " * 4, end="")
for name, dt in res.items():
print("{}: {:.6f} ".format(name, dt), end="")
print("")
2018-04-05 22:07:33 +00:00
def run_native(hostpython, code):
output = subprocess.check_output(
[hostpython.resolve(), "-c", code],
2018-08-03 17:10:18 +00:00
cwd=Path(__file__).resolve().parent,
env={"PYTHONPATH": str(Path(__file__).resolve().parents[1] / "src")},
2018-04-05 22:07:33 +00:00
)
return float(output.strip().split()[-1])
def run_wasm(code, selenium):
selenium.run(code)
2018-04-09 14:39:52 +00:00
try:
runtime = float(selenium.logs.split("\n")[-1])
except ValueError:
print(selenium.logs)
raise
2018-04-05 22:07:33 +00:00
return runtime
def run_all(hostpython, selenium_backends, code):
2018-04-05 22:07:33 +00:00
a = run_native(hostpython, code)
result = {"native": a}
for browser_name, selenium in selenium_backends.items():
dt = run_wasm(code, selenium)
result[browser_name] = dt
2018-04-05 22:07:33 +00:00
return result
def get_pystone_benchmarks():
yield "pystone", ("import pystone\n" "pystone.main(pystone.LOOPS)\n")
2018-04-05 22:07:33 +00:00
def parse_numpy_benchmark(filename):
lines = []
with open(filename) as fp:
for line in fp:
m = re.match(r"^#\s*(setup|run): (.*)$", line)
2018-04-05 22:07:33 +00:00
if m:
line = "{} = {!r}\n".format(m.group(1), m.group(2))
2018-04-05 22:07:33 +00:00
lines.append(line)
return "".join(lines)
2018-04-05 22:07:33 +00:00
def get_numpy_benchmarks():
root = Path(__file__).resolve().parent / "benchmarks"
2018-08-03 16:48:22 +00:00
for filename in root.iterdir():
name = filename.stem
2018-04-05 22:07:33 +00:00
if name in SKIP:
continue
2018-08-03 17:10:18 +00:00
content = parse_numpy_benchmark(filename)
2018-04-05 22:07:33 +00:00
content += (
"import numpy as np\n"
"_ = np.empty(())\n"
2018-04-05 22:07:33 +00:00
"setup = setup + '\\nfrom __main__ import {}'\n"
"from timeit import Timer\n"
"t = Timer(run, setup)\n"
"r = t.repeat(11, 40)\n"
"r.remove(min(r))\n"
"r.remove(max(r))\n"
"print(np.mean(r))\n".format(name)
)
2018-04-05 22:07:33 +00:00
yield name, content
def get_benchmarks():
yield from get_pystone_benchmarks()
yield from get_numpy_benchmarks()
def main(hostpython):
with conftest.spawn_web_server() as (hostname, port, log_path):
results = {}
selenium_backends = {}
b = {"native": float("NaN")}
browser_cls = [
("firefox", conftest.FirefoxWrapper),
("chrome", conftest.ChromeWrapper),
]
for name, cls in browser_cls:
t0 = time()
selenium_backends[name] = cls(port)
b[name] = time() - t0
# pre-load numpy for the selenium instance used in benchmarks
selenium_backends[name].load_package("numpy")
results["selenium init"] = b
print_entry("selenium init", b)
# load packages
for package_name in ["numpy"]:
b = {"native": float("NaN")}
for browser_name, cls in browser_cls:
selenium = cls(port)
try:
t0 = time()
selenium.load_package(package_name)
b[browser_name] = time() - t0
finally:
selenium.driver.quit()
results["load " + package_name] = b
print_entry("load " + package_name, b)
for name, content in get_benchmarks():
results[name] = run_all(hostpython, selenium_backends, content)
print_entry(name, results[name])
for selenium in selenium_backends.values():
selenium.driver.quit()
2018-04-05 22:07:33 +00:00
return results
if __name__ == "__main__":
2018-08-03 17:10:18 +00:00
results = main(Path(sys.argv[-2]).resolve())
with open(sys.argv[-1], "w") as fp:
2018-04-05 22:07:33 +00:00
json.dump(results, fp)