GitLab will be upgraded on 30 Jan 2023 from 2.00 pm (AEDT) to 3.00 pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

perfcmp.py 4.12 KB
Newer Older
1
2
3
4
5
"""
Performance comparison
"""
from time import time
from tempfile import mkdtemp
John Zhang's avatar
John Zhang committed
6
import py, os, sys
7
8
9
10
11
12
import subprocess as subp
import ctypes

from rpython.translator.interactive import Translation
from rpython.config.translationoption import set_opt_level

13
from util import libext, preload_libmu
14

John Zhang's avatar
John Zhang committed
15
16
17
perf_target_dir = py.path.local(__file__).dirpath().join('perftarget')


18
19
20
CPYTHON = os.environ.get('CPYTHON', 'python')
PYPY = os.environ.get('PYPY', 'pypy')
RPYTHON = os.environ.get('RPYTHON', None)
John Zhang's avatar
John Zhang committed
21
CC = os.environ.get('CC', 'clang')
22

23

24
def run(cmd):
John Zhang's avatar
John Zhang committed
25
    print ' '.join(cmd)
26
27
28
    p = subp.Popen(cmd, stdout=subp.PIPE, stderr=subp.PIPE)
    return p.communicate()

John Zhang's avatar
John Zhang committed
29

30
31
32
33
34
def get_c_function(lib, f):
    from ctypes import CDLL
    name = f.__name__
    return getattr(CDLL(lib.strpath), 'pypy_g_' + name)

John Zhang's avatar
John Zhang committed
35

36
def perf_fibonacci():
John Zhang's avatar
John Zhang committed
37
    from perftarget.fibonacci import fib
38
39
40
    tmpdir = py.path.local(mkdtemp())
    print tmpdir

41
42
    py_file = perf_target_dir.join('fibonacci.py')
    c_file = perf_target_dir.join('fibonacci.c')
43

44
    def run_cpython(N):
45
46
47
        out, _ = run([CPYTHON, py_file.strpath, str(N)])
        return float(out)

48
    def run_pypy_nojit(N):
49
50
51
        out, _ = run([PYPY, '--jit', 'off', py_file.strpath, str(N)])
        return float(out)

52
53
    def run_pypy(N):
        out, _ = run([PYPY, py_file.strpath, str(N)])
54
55
56
        return float(out)

    def compile_rpython_c():
57
        t = Translation(fib, [int],
58
59
60
61
                        gc='none')
        set_opt_level(t.config, '3')
        t.ensure_opt('gc', 'none')
        libpath = t.compile_c()
62
        fnp = getattr(ctypes.CDLL(libpath.strpath), 'pypy_g_' + fib.__name__)
63
64
65
        return fnp

    def compile_rpython_c_jit():
66
        t = Translation(fib, [int],
67
68
69
70
                        gc='none')
        set_opt_level(t.config, 'jit')
        t.ensure_opt('gc', 'none')
        libpath = t.compile_c()
71
        fnp = getattr(ctypes.CDLL(libpath.strpath), 'pypy_g_' + fib.__name__)
72
73
        return fnp

John Zhang's avatar
John Zhang committed
74
75
76
77
78
79
    def compile_c():
        libpath = tmpdir.join('libfibonacci' + libext)
        run([CC, '-fpic', '--shared', '-o', libpath.strpath, c_file.strpath])
        lib = ctypes.CDLL(libpath.strpath)
        return lib.fib

80
    def compile_rpython_mu():
81
        preload_libmu()
82
        t = Translation(fib, [int],
83
84
85
86
87
88
89
90
                        backend='mu', muimpl='fast', mucodegen='api', mutestjit=True)
        set_opt_level(t.config, '3')
        db, bdlgen, fnc_name = t.compile_mu()
        libname = 'lib%(fnc_name)s.dylib' % locals()
        bdlgen.mu.compile_to_sharedlib(libname, [])
        libpath = py.path.local().join('emit', libname)
        fnp = getattr(ctypes.CDLL(libpath.strpath), fnc_name)
        return fnp
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    def get_average_time(run_fnc, args, warmup=5, iterations=100):
        for i in range(warmup):
            run_fnc(*args)

        total = 0.0
        for i in range(iterations):
            total += run_fnc(*args)
        return total / iterations

    def get_average_time_compiled(compile_fnc, args, warmup=5, iterations=100):
        def run_funcptr(fnp, N):
            t0 = time()
            fnp(N)
            t1 = time()
            return t1 - t0

        fnp = compile_fnc()
        return get_average_time(lambda *a: run_funcptr(fnp, *a), args, warmup, iterations)

111
    N = 30
John Zhang's avatar
John Zhang committed
112
113
114
115
116
117
118
119
120
121
    warmup = 0
    iterations = 1

    t_cpython = get_average_time(run_cpython, [N], warmup, iterations=iterations)
    t_pypy_nojit = get_average_time(run_pypy_nojit, [N], warmup, iterations=iterations)
    t_pypy = get_average_time(run_pypy, [N], warmup, iterations=iterations)
    t_rpyc = get_average_time_compiled(compile_rpython_c, [N], warmup, iterations=iterations)
    t_rpyc_jit = get_average_time_compiled(compile_rpython_c_jit, [N], warmup, iterations=iterations)
    t_rpyc_mu = get_average_time_compiled(compile_rpython_mu, [N], warmup, iterations=iterations)
    t_c = get_average_time_compiled(compile_c, [N], warmup, iterations=iterations)
122
123
124
125
126
127
    print "CPython:", t_cpython
    print "PyPy (no JIT):", t_pypy_nojit
    print "PyPy:", t_pypy
    print "RPython C:", t_rpyc
    print "RPython C (with JIT):", t_rpyc_jit
    print "RPython Mu Zebu:", t_rpyc_mu
John Zhang's avatar
John Zhang committed
128
    print "C:", t_c
129
130
131

if __name__ == '__main__':
    perf_fibonacci()