为了账号安全,请及时绑定邮箱和手机立即绑定

与多行循环相比,单行循环是否可以节省 python 代码的运行时间?

与多行循环相比,单行循环是否可以节省 python 代码的运行时间?

人到中年有点甜 2023-10-31 16:11:30
我想知道如何减少程序的运行时间。使用单线循环比多线循环更有效吗?#is this more efficienttotal_data = [[arr1[j][i] for j in range(3)]+ arr2[i][0] for i in range(10000)]#instead oftotal_data = []for i in range(10000):    arr3 = []    a2 = arr2[i][0]    for j in range(3):        arr3.append(arr1[j][i])    total_data.append(arr3+a2)另外,在调用函数时,使用map是否比for循环更节省时间?#thisf1 = map(func1, var1, var2)arr = map(func2, f2, var3, var4)#instead of thisarr = []for i in range(1000):    f1 = func1(var1(i), var2(i))    f2 = func2(f1(i))    arr.append(f2, var3, var4)我的数据集很大,每个函数运行时间也很可观,所以我想尽可能减少时间。我想从根本上知道增加Python中同一循环的行数是否会增加时间。
查看完整描述

3 回答

?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

更多代码行是否意味着性能降低的问题是有缺陷的,因为两者都不是less lines ≠ performance ≠ more lines。性能取决于 Python 代码如何解析为执行它的底层 C 函数调用,这主要是解析器/解释器的实现细节,与行数没有一一对应。

也就是说,在选择循环、列表理解和映射时需要考虑以下几点。

  • 当代码的目的是创建某个内容的列表时,列表推导式通常比循环更快。据我所知,这与第二次调用追加方法有关,而且因为增量列表构造可能会导致列表大小调整,从而导致一些内存重新分配开销。

  • 无论在哪里调用,调用 python 函数都是一个缓慢的操作。引用这个伟大的答案:A function call needs to manipulate the stack, pushing the local frame onto it, creating a new frame, then clear it all up again when the function returns.一个例外是用 C 编写的函数,例如来自操作员模块的函数,它们比本地 Python 对应项稍快。

也就是说,我已经使用与此类似的代码进行了一些分析,并且我的测试表明循环是最慢的选项。有趣的是,测试还表明地图比列表理解稍快(与链接的答案相反)。代码及结果如下:

ls = list(range(1000000))


def f(x):

    return x+1


def list_comprehension(ls):

    return [f(x) for x in ls]


def for_loop(ls):

    arr = []

    for x in ls:

        arr.append(f(x))

    return arr


def map_(ls):

    return list(map(f, ls))


if __name__ == "__main__":

    import cProfile

    for fn in [list_comprehension, for_loop, map_]:

        print('=' * 25)

        print("Profiling:", fn.__name__)

        print('=' * 25)

        pr = cProfile.Profile()

        for i in range(1000):

            pr.runcall(fn, ls)

        pr.create_stats()

        pr.print_stats()


# Output

=========================

Profiling: list_comprehension

=========================

         1000003000 function calls in 235.641 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

1000000000  104.000    0.000  104.000    0.000 aa.py:5(f)

     1000    0.008    0.000  235.640    0.236 aa.py:8(list_comprehension)

     1000  131.632    0.132  235.632    0.236 aa.py:9(<listcomp>)

     1000    0.001    0.000    0.001    0.000 {method 'disable' of '_lsprof.Profiler' objects}



=========================

Profiling: for_loop

=========================

         2000002000 function calls in 410.884 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

     1000  242.083    0.242  410.883    0.411 aa.py:11(for_loop)

1000000000  107.727    0.000  107.727    0.000 aa.py:5(f)

1000000000   61.073    0.000   61.073    0.000 {method 'append' of 'list' objects}

     1000    0.001    0.000    0.001    0.000 {method 'disable' of '_lsprof.Profiler' objects}



=========================

Profiling: map_

=========================

         1000002000 function calls in 205.035 seconds


   Ordered by: standard name


   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

     1000  102.451    0.102  205.034    0.205 aa.py:17(map_)

1000000000  102.583    0.000  102.583    0.000 aa.py:5(f)

     1000    0.001    0.000    0.001    0.000 {method 'disable' of '_lsprof.Profiler' objects}

无论如何,在这种情况下最好的办法是写下所有不同的版本并自己进行分析,而不是依赖一般假设。


查看完整回答
反对 回复 2023-10-31
?
ibeautiful

TA贡献1993条经验 获得超5个赞

单行代码可能比较长的代码更快,但这不是一般规则。一些允许非常紧凑的代码的 python 函数(如 any()、all() 等)经过优化,可以非常快速地执行,并且可能比 (例如)几个执行相同工作的嵌套循环。编译器/解释器并不真正关心它必须处理多少文本(除非您的代码由数千行代码组成)。单行是首选,因为它节省了空间并使代码更具可读性。



查看完整回答
反对 回复 2023-10-31
?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

行数与代码的执行完全无关。py 文件将被读取一次、解析和编译。随后,将执行编译后的代码。

换句话说,如果您创建一个包含 10 GB 空白的文件,是的,这会影响解析时间,但即使如此,执行也不会受到影响。

两种变体之间的区别在于,一种使用列表理解来创建列表,而另一种则创建一个空列表,然后填充它。我的直觉是,列表理解理论上更容易优化,但如果你真的关心微小的差异,你应该分析它。

另一方面,执行时间的微小差异很少会导致代码看起来更糟糕,因此默认情况下您应该始终选择更优雅的解决方案。


查看完整回答
反对 回复 2023-10-31
  • 3 回答
  • 0 关注
  • 124 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信