#!python ## Copyright (c) 2020-2021 Thakee Nathees ## Copyright (c) 2021-2022 Pocketlang Contributors ## Distributed Under The MIT License import re, os, sys import subprocess, platform from shutil import which from os.path import join, abspath, dirname, relpath, exists ## Absolute path of this file's directory. THIS_PATH = abspath(dirname(__file__)) ## Output debug cli executable's directory. POCKET_BINARY_DIR = abspath(join(THIS_PATH, "../build/Release/bin/")) ## Pocket lang root directory. All the listed paths bellow are relative to ## the BENCHMARKS_DIR. BENCHMARKS_DIR = abspath(join(THIS_PATH, "../tests/benchmarks")) ## A list of benchmark directories, relative to BENCHMARKS_DIR BENCHMARKS = ( "factors", "fib", "list", "loop", "primes", ) ## Map the files extension with it's interpreter. (executable, extension). INTERPRETERS = { 'pocketlang' : ('pocket', '.pk'), 'python' : ('python3', '.py'), 'wren' : ('wren', '.wren'), 'ruby' : ('ruby', '.rb'), 'lua' : ('lua', '.lua'), ## Javascript on Node is using V8 that compiles the function before calling it ## which makes it way faster than every other language in this list, we're ## only comparing byte-code interpreted VM languages. Node is the odd one out. #'javascript' : ('node', '.js'), } ## The html template to display the report. HTML_TEMPLATE = "template.html" def main(): results = dict() update_interpreters() for benchmark in BENCHMARKS: print_title(benchmark.title()) for lang in INTERPRETERS: interp, ext = INTERPRETERS[lang] source = abspath(join(BENCHMARKS_DIR, benchmark, benchmark + ext)) if not exists(source): continue print(" %-10s : "%lang, end=''); sys.stdout.flush() result = subprocess.run([interp, source], stdout=subprocess.PIPE, stderr=subprocess.PIPE) time = get_time(result.stdout.decode('utf8')) print('%.6fs' % float(time)) if benchmark not in results: results[benchmark] = [] results[benchmark].append([lang, time]) display_results(results) ## This will return the path of the pocket binary (on different platforms). ## The debug version of it for enabling the assertions. def get_pocket_binary(name, fail): system = platform.system() if system not in ("Windows", "Linux", "Darwin"): error_exit("Unsupported platform") binary = join(POCKET_BINARY_DIR, name) if system == "Windows": binary += ".exe" if not exists(binary): if fail: error_exit(f"Pocket interpreter not found at: '{binary}'") else: return None return binary ## Set the pocketlang path for the current system to the compiled output. def update_interpreters(): pocket = get_pocket_binary("pocket", True) pocket_older = get_pocket_binary("pocket_older", False) global INTERPRETERS INTERPRETERS['pocketlang'] = (pocket, '.pk') ## Add if older version of pocketlang if exists. if pocket_older is not None: INTERPRETERS['pk-older'] = (pocket_older, '.pk') if 'python' in INTERPRETERS and platform.system() == "Windows": INTERPRETERS['python'] = ('python', '.py') missing = [] for lang in INTERPRETERS: interpreter = INTERPRETERS[lang][0] print('%-27s' % (' Searching for %s ' % lang), end='') if which(interpreter): print(f"-- {colmsg('found', COL_GREEN)}") else: print(f"-- {colmsg('missing', COL_YELLOW)}") missing.append(lang) for miss in missing: INTERPRETERS.pop(miss) ## Match 'elapsed: