高阶函数vs循环 - 运行时间和内存效率?

Bha*_*rat 8 python higher-order-functions

使用高阶函数和Lambda会使运行时间和内存效率更好还是更差?例如,要乘以列表中的所有数字:

nums = [1,2,3,4,5]
prod = 1
for n in nums:
    prod*=n
Run Code Online (Sandbox Code Playgroud)

VS

prod2 = reduce(lambda x,y:x*y , nums)
Run Code Online (Sandbox Code Playgroud)

除了较少的代码行/使用功能方法之外,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) 
Run Code Online (Sandbox Code Playgroud)

这是我的结果:

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
Run Code Online (Sandbox Code Playgroud)

平均循环方法似乎比使用HOF更快.

Ray*_*ger 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
Run Code Online (Sandbox Code Playgroud)


小智 1

根据我的经验,循环可以非常快地完成任务,只要它们嵌套得不是太深,并且对于复杂的高等数学运算,对于简单的运算和单层循环,它可以与任何其他方式一样快,甚至更快,只要仅使用整数作为一个或多个循环的索引,这实际上也取决于您在做什么

另外,高阶函数很可能会产生与循环程序版本一样多的循环,甚至可能会慢一些,您必须对它们两者进行计时......只是为了确定。