Четыре реализации:
Код:
#!/usr/bin/env python
""" weave_factorial.py
"""
# [weave] factorial() as extension module in C++
from scipy.weave import ext_tools
def build_factorial_ext():
func = ext_tools.ext_function(
'factorial',
r"""
unsigned long long i = 1;
for ( ; n > 1; --n)
i *= n;
PyObject *o = PyLong_FromUnsignedLongLong(i);
return_val = o;
Py_XDECREF(o);
""",
['n'],
{'n': 1}, # effective type declaration
{})
mod = ext_tools.ext_module('factorial_ext')
mod.add_function(func)
mod.compile()
try: from factorial_ext import factorial as factorial_weave
except ImportError:
build_factorial_ext()
from factorial_ext import factorial as factorial_weave
# [python] pure python procedural factorial()
def factorial_python(n):
i = 1
while n > 1:
i *= n
n -= 1
return i
# [psyco] factorial() psyco-optimized
try:
import psyco
factorial_psyco = psyco.proxy(factorial_python)
except ImportError:
pass
# [list] list-lookup factorial()
factorials = map(factorial_python, range(21))
factorial_list = lambda n: factorials[n]
<час> Измеряют относительный уровень:
$ python -mtimeit \
-s "from weave_factorial import factorial_$label as f" "f($n)"
n = 12
n = 20
µ секунда стоит в течение многих микросекунд.
Взгляните на Data.Foldable . Он определяет класс типа, который делает именно то, что вы хотите.
What какой тип массива вы используете? Возможно, вы сможете просто свернутьM над индексным пространством.
Используя Data.Foldable
, вы можете foldr
/ foldl
и массив
точно так же, как вы можете list.
Другой вариант - преобразовать массив
обратно в список с помощью elems
, а затем foldr
или foldl
над списком.