#!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 ## The absolute path of this file, when run as a script. ## This file is not intended to be included in other files at the moment. THIS_PATH = abspath(dirname(__file__)) ## A list of benchmark directories, relative to THIS_PATH 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'), } ## Map from systems to the relative pocket binary path. SYSTEM_TO_POCKET_PATH = { "current" : { "Windows": "..\\..\\build\\release\\bin\\pocket.exe", "Linux" : "../../build/release/pocket", "Darwin" : "../../build/release/pocket", }, ## This maps the older version of pocket in the system path, to compare ## pocketlang with it's older version. "older" : { "Windows": "..\\..\\build\\release\\bin\\pocket_older.exe", "Linux" : "../../build/release/pocket_older", "Darwin" : "../../build/release/pocket_older", } } ## 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(THIS_PATH, 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) ## Set the pocketlang path for the current system to the compiled output. def update_interpreters(): system = platform.system() if system not in SYSTEM_TO_POCKET_PATH['current']: print("Unsupported platform %s" % system) sys.exit(1) global INTERPRETERS pocket = abspath(join(THIS_PATH, SYSTEM_TO_POCKET_PATH['current'][system])) pocket_older = abspath(join(THIS_PATH, SYSTEM_TO_POCKET_PATH['older'][system])) if not exists(pocket): print(f"{colmsg('Error', COL_RED)}: " + "Pocket interpreter not found at: '%s'" % pocket) sys.exit(1) INTERPRETERS['pocketlang'] = (pocket, '.pk') ## Add if older version of pocketlang if exists. if exists(pocket_older): INTERPRETERS['pk-older'] = (pocket_older, '.pk') if 'python' in INTERPRETERS and 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: