Created
November 17, 2020 20:26
-
-
Save tsangwpx/f8baecec8c6b275233dd4710e47f83c7 to your computer and use it in GitHub Desktop.
Performance comparsion between long if-else and mapped function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def fn_ifelse(i): | |
if i == 0: | |
return i | |
elif i == 1: | |
return i | |
elif i == 2: | |
return i | |
elif i == 3: | |
return i | |
elif i == 4: | |
return i | |
elif i == 5: | |
return i | |
elif i == 6: | |
return i | |
else: | |
return i | |
def fn_table_build(): | |
def sub_0(i): | |
return i | |
def sub_1(i): | |
return i | |
def sub_2(i): | |
return i | |
def sub_3(i): | |
return i | |
def sub_4(i): | |
return i | |
def sub_5(i): | |
return i | |
def sub_6(i): | |
return i | |
def sub_7(i): | |
return i | |
table = { | |
0: sub_0, | |
1: sub_1, | |
2: sub_2, | |
3: sub_3, | |
4: sub_4, | |
5: sub_5, | |
6: sub_6, | |
} | |
def fn_main(i): | |
return table.get(i, sub_7)(i) | |
return fn_main | |
fn_table = fn_table_build() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Roughly 12 branches can beat mapped function | |
""" | |
from __future__ import annotations | |
import itertools | |
from timeit import timeit | |
from typing import List | |
def func_body(i): | |
# all are identity function | |
return "return i" | |
def fn_source(name, args, body: List[str]): | |
lines = ['def %s(%s):' % (name, ','.join(args))] | |
lines.extend([f" {s}" for s in body]) | |
return '\n'.join(lines) | |
def ifelse_setup_code(n): | |
assert n >= 2 | |
body = [] | |
for i in range(n): | |
if i == 0: | |
cond = f"if i == {i}:" | |
elif i == n - 1: | |
cond = f"else:" | |
else: | |
cond = f"elif i == {i}:" | |
body.extend(( | |
cond, | |
f' {func_body(i)}', | |
)) | |
return fn_source('fn_ifelse', ('i',), body) | |
def map_setup_code(n): | |
assert n >= 2 | |
def create_subfn(id_): | |
return fn_source(f'sub_{id_}', ('i',), [func_body(id_)]) | |
lines = [] | |
for i in range(n): | |
lines.extend(create_subfn(i).split('\n')) | |
lines.append('table = {') | |
for i in range(n - 1): | |
lines.append(f' {i}: sub_{i},') | |
lines.append('}') | |
main_body = [] | |
main_body.append(f'return table.get(i, sub_{n - 1})(i)') | |
# | |
# main_body.extend(( | |
# 'try:', | |
# ' return table[i](i)', | |
# 'except KeyError:', | |
# f' return sub_{n - 1}(i)', | |
# )) | |
lines.extend(fn_source('fn_main', ('i',), main_body).split('\n')) | |
lines.append('return fn_main') | |
s = fn_source('fn_table_build', (), lines) | |
return '\n'.join(itertools.chain(s.split('\n'), [ | |
'fn_table = fn_table_build()', | |
])) | |
def main(): | |
for n in range(10, 32): | |
source = '\n'.join((ifelse_setup_code(n), map_setup_code(n))) | |
ns = {} | |
exec(source, None, ns) | |
fn_ifelse = ns['fn_ifelse'] | |
fn_table = ns['fn_table'] | |
assert fn_ifelse(n // 2) == n // 2, n | |
assert fn_table(n // 2) == n // 2, n | |
number = 1_000_000 | |
print('n', n) | |
# print(source) | |
print('ifelse', timeit('[fn(i) for i in range(n)]', 'fn = fn_ifelse', globals=locals(), number=number) / n) | |
print('table', timeit('[fn(i) for i in range(n)]', 'fn = fn_table', globals=locals(), number=number) / n) | |
print() | |
if __name__ == '__main__': | |
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
n 10 | |
ifelse 0.18849027999999998 | |
table 0.20733889000000003 | |
n 11 | |
ifelse 0.19307480909090913 | |
table 0.20729382727272727 | |
n 12 | |
ifelse 0.20221672499999999 | |
table 0.20399962499999993 | |
n 13 | |
ifelse 0.20751689230769224 | |
table 0.2013621461538461 | |
n 14 | |
ifelse 0.21670767857142867 | |
table 0.1975107357142856 | |
n 15 | |
ifelse 0.22186927333333345 | |
table 0.19777445333333313 | |
n 16 | |
ifelse 0.22301578749999984 | |
table 0.19646908125000007 | |
n 17 | |
ifelse 0.2332971823529411 | |
table 0.19414692941176442 | |
n 18 | |
ifelse 0.2459139055555555 | |
table 0.19327038333333332 | |
n 19 | |
ifelse 0.24255543684210548 | |
table 0.19525191578947362 | |
n 20 | |
ifelse 0.2588372049999997 | |
table 0.19517728999999945 | |
n 21 | |
ifelse 0.26504744285714327 | |
table 0.19126317142857172 | |
n 22 | |
ifelse 0.290177722727273 | |
table 0.1923927818181813 | |
n 23 | |
ifelse 0.2850982608695652 | |
table 0.18657619130434802 | |
n 24 | |
ifelse 0.2944755791666669 | |
table 0.1851711708333331 | |
n 25 | |
ifelse 0.2965222399999999 | |
table 0.18683115199999975 | |
n 26 | |
ifelse 0.3051656884615382 | |
table 0.18965108076923143 | |
n 27 | |
ifelse 0.3249459555555558 | |
table 0.1891015259259253 | |
n 28 | |
ifelse 0.3348370678571432 | |
table 0.19059417500000006 | |
n 29 | |
ifelse 0.33812261034482805 | |
table 0.18927325862068953 | |
n 30 | |
ifelse 0.3402334599999998 | |
table 0.18482614999999972 | |
n 31 | |
ifelse 0.3501115806451618 | |
table 0.18180615483870974 | |
Process finished with exit code 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment