Commit e292668e authored by John Zhang's avatar John Zhang

add quicksort into performance measurement script

parent 3cee78aa
......@@ -97,10 +97,7 @@ def compile_c(config):
return fnp
def get_stat(run_fnc, config, warmup=5, iterations=100):
for i in range(warmup):
run_fnc(config)
def get_stat(run_fnc, config, iterations=100):
times = []
for i in range(iterations):
times.append(run_fnc(config))
......@@ -117,7 +114,7 @@ def get_stat(run_fnc, config, warmup=5, iterations=100):
return {'average': avg, 't_min': t_min, 't_max': t_max, 'std_dev': t_std}
def get_stat_compiled(compile_fnc, config, warmup=5, iterations=100):
def get_stat_compiled(compile_fnc, config, iterations=100):
def run_funcptr(fnp, config):
args = config['setup'](*config['setup_args'])
t0 = time()
......@@ -127,7 +124,7 @@ def get_stat_compiled(compile_fnc, config, warmup=5, iterations=100):
return t1 - t0
fnp = compile_fnc(config)
return get_stat(lambda config: run_funcptr(fnp, config), config, warmup, iterations)
return get_stat(lambda config: run_funcptr(fnp, config), config, iterations)
def get_display_str(stat):
......@@ -138,15 +135,15 @@ def get_display_str(stat):
return output % stat
def perf(config, warmup, iterations):
def perf(config, iterations):
results = {
'cpython': get_stat(run_cpython, config, warmup, iterations=iterations),
'pypy_nojit': get_stat(run_pypy_nojit, config, warmup, iterations=iterations),
'pypy': get_stat(run_pypy, config, warmup, iterations=iterations),
'rpy_c': get_stat_compiled(compile_rpython_c, config, warmup, iterations=iterations),
'rpy_c_jit': get_stat_compiled(compile_rpython_c_jit, config, warmup, iterations=iterations),
'rpy_mu': get_stat_compiled(compile_rpython_mu, config, warmup, iterations=iterations),
'c': get_stat_compiled(compile_c, config, warmup=warmup, iterations=iterations),
'cpython': get_stat(run_cpython, config, iterations=iterations),
'pypy_nojit': get_stat(run_pypy_nojit, config, iterations=iterations),
'pypy': get_stat(run_pypy, config, iterations=iterations),
'rpy_c': get_stat_compiled(compile_rpython_c, config, iterations=iterations),
'rpy_c_jit': get_stat_compiled(compile_rpython_c_jit, config, iterations=iterations),
'rpy_mu': get_stat_compiled(compile_rpython_mu, config, iterations=iterations),
'c': get_stat_compiled(compile_c, config, iterations=iterations),
}
for python, result in results.items():
......@@ -164,7 +161,7 @@ def save_results(test_name, results):
json.dump(results, fp, indent=4, separators=(',', ':'))
def perf_fibonacci(N, warmup, iterations):
def perf_fibonacci(N, iterations):
from perftarget.fibonacci import fib
tmpdir = py.path.local(mkdtemp())
print tmpdir
......@@ -183,12 +180,12 @@ def perf_fibonacci(N, warmup, iterations):
'libpath_c': tmpdir.join('libfibonacci_c.dylib')
}
results = perf(config, warmup, iterations)
results = perf(config, iterations)
results['problem_size'] = N
return results
def perf_arraysum(N, warmup, iterations):
def perf_arraysum(N, iterations):
from perftarget.arraysum import arraysum, setup, teardown
tmpdir = py.path.local(mkdtemp())
print tmpdir
......@@ -207,19 +204,48 @@ def perf_arraysum(N, warmup, iterations):
'libpath_c': tmpdir.join('libfibonacci_c.dylib')
}
results = perf(config, warmup, iterations)
results = perf(config, iterations)
results['problem_size'] = N
return results
def perf_quicksort(N, iterations):
from perftarget.quicksort import quicksort, setup, teardown
tmpdir = py.path.local(mkdtemp())
print tmpdir
config = {
'py_file': perf_target_dir.join('quicksort.py'),
'c_file': perf_target_dir.join('quicksort.c'),
'rpy_fnc': quicksort,
'c_sym_name': 'quicksort',
'llarg_ts': [rffi.CArrayPtr(rffi.LONGLONG), lltype.Signed, lltype.Signed],
'llres_t': lltype.Void,
'setup_args': (N,),
'setup': setup,
'teardown': teardown,
'libpath_mu': tmpdir.join('libquicksort_mu.dylib'),
'libpath_c': tmpdir.join('libquicksort_c.dylib')
}
results = perf(config, iterations)
results['problem_size'] = N
return results
def test_functional_fibonacci():
save_results('fibonacci', perf_fibonacci(5, 0, 1))
save_results('fibonacci', perf_fibonacci(5, 1))
def test_functional_arraysum():
save_results('arraysum', perf_arraysum(100, 0, 1))
save_results('arraysum', perf_arraysum(100, 1))
def test_functional_quicksort():
save_results('quicksort', perf_quicksort(100, 1))
if __name__ == '__main__':
save_results('fibonacci', perf_fibonacci(40, 5, 20))
save_results('arraysum', perf_arraysum(1000000, 5, 20))
save_results('fibonacci', perf_fibonacci(40, 20))
save_results('arraysum', perf_arraysum(1000000, 20))
save_results('quicksort', perf_quicksort(1000000, 20))
#include <stdint.h>
void swap(int64_t* arr, int64_t i, int64_t j) {
int64_t t;
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
int64_t partition(int64_t* arr, int64_t idx_low, int64_t idx_high) {
int64_t pivot, i, j;
pivot = arr[idx_high];
i = idx_low;
for (j = idx_low; j < idx_high; j ++) {
if (arr[j] < pivot) {
swap(arr, i, j);
i += 1;
}
}
swap(arr, i, idx_high);
return i;
}
void quicksort(int64_t* arr, int64_t start, int64_t end) {
int64_t p;
if (start < end) {
p = partition(arr, start, end);
quicksort(arr, start, p - 1);
quicksort(arr, p + 1, end);
}
}
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rlib.jit import JitDriver
d = JitDriver(greens=[], reds='auto')
# algorithm taken from Wikipedia
def swap(arr, i, j):
t = arr[i]
arr[i] = arr[j]
arr[j] = t
def partition(arr, idx_low, idx_high):
pivot = arr[idx_high]
i = idx_low
for j in range(idx_low, idx_high):
d.jit_merge_point()
if arr[j] < pivot:
swap(arr, i, j)
i += 1
swap(arr, i, idx_high)
return i
def quicksort(arr, start, end):
if start < end:
p = partition(arr, start, end)
quicksort(arr, start, p - 1)
quicksort(arr, p + 1, end)
def setup(n):
lst, _ = rand_list_of(n)
arr = lltype.malloc(rffi.CArray(rffi.LONGLONG), n, flavor='raw')
for i, k in enumerate(lst):
arr[i] = k
return arr, 0, n - 1
def teardown(arr, s, e):
lltype.free(arr, 'raw')
def rand_list_of(n):
# 32 extend to 64-bit integers (to avoid overflow in summation
from random import randrange, getstate
init_state = getstate()
return [rffi.r_longlong(randrange(-(1 << 31), (1 << 31) - 1)) for _ in range(n)], init_state
def measure(N):
args = setup(N)
from time import time
t0 = time()
quicksort(*args)
t1 = time()
teardown(*args)
return t0, t1
def rpy_entry(N):
t0, t1 = measure(N)
# from rpython.rlib import rfloat
# print rfloat.double_to_string(t1 - t0, 'e', %(fprec)d, rfloat.DTSF_ADD_DOT_0)
return t1 - t0
if __name__ == '__main__':
import sys
t0, t1 = measure(int(sys.argv[1]))
print '%.15f' % (t1 - t0)
def target(*args):
from rpython.rlib.entrypoint import export_symbol
export_symbol(rpy_entry)
return rpy_entry, [int]
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment