使用高阶函数& Lambdas让运行时间和时间记忆效率更好还是更差? 例如,要将列表中的所有数字相乘:
nums = [1,2,3,4,5]
prod = 1
for n in nums:
prod*=n
VS
prod2 = reduce(lambda x,y:x*y , nums)
除了较少的代码行/使用功能方法之外,HOF版本是否比循环版本有任何优势?
修改
我无法将此作为答案添加,因为我没有所需的声誉。 我绑定了循环和放大器使用@ DSM
建议的timeit的HOF方法def test1():
s= """
nums = [a for a in range(1,1001)]
prod = 1
for n in nums:
prod*=n
"""
t = timeit.Timer(stmt=s)
return t.repeat(repeat=10,number=100)
def test2():
s="""
nums = [a for a in range(1,1001)]
prod2 = reduce(lambda x,y:x*y , nums)
"""
t = timeit.Timer(stmt=s)
return t.repeat(repeat=10,number=100)
这是我的结果:
Loop:
[0.08340786340144211, 0.07211491653462579, 0.07162720686361926, 0.06593182661083438, 0.06399049758613146, 0.06605228229559557, 0.06419744588664211, 0.0671893658461038, 0.06477527090075941, 0.06418023793167627]
test1 average: 0.0644778902685
HOF:
[0.0759414223099324, 0.07616920129277016, 0.07570730355421262, 0.07604965128984942, 0.07547092059389193, 0.07544737286604364, 0.075532959799953, 0.0755039779810629, 0.07567424616704144, 0.07542563650187661]
test2 average: 0.0754917512762
平均循环方法似乎比使用HOF更快。
答案 0 :(得分:7)
高阶函数可以非常快。
例如,map(ord, somebigstring)
比同等列表理解[ord(c) for c in somebigstring]
更快。前者获胜有三个原因:
map()将结果字符串预先调整为 somebigstring 的长度。相比之下,list-comprehension在增长时必须多次调用 realloc()。
map()只需对 ord 进行一次查找,首先检查全局变量,然后在内置函数中检查并查找它。列表理解必须在每次迭代时重复这项工作。
地图的内部循环以C速度运行。列表推导的循环体是一系列纯Python步骤,每个步骤都需要由eval-loop调度或处理。
以下是确认预测的一些时间:
>>> from timeit import Timer
>>> print min(Timer('map(ord, s)', 's="x"*10000').repeat(7, 1000))
0.808364152908
>>> print min(Timer('[ord(c) for c in s]', 's="x"*10000').repeat(7, 1000))
1.2946639061
答案 1 :(得分:1)
从我的经验循环可以非常快速地做事,只要它们没有嵌套得太深,并且具有复杂的高级数学运算,对于简单的操作和单层循环它可以像任何其他方式一样快,可能更快,只要只使用整数作为循环或循环的索引,它实际上取决于你正在做什么
同样可能的是,高阶函数将产生尽可能多的循环 作为循环程序版本,甚至可能会慢一点,你必须给他们两个时间......只是为了确定。