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

我想知道如何减少程序的运行时间。使用单线循环比多线循环更有效吗?


#is this more efficient


total_data = [[arr1[j][i] for j in range(3)]+ arr2[i][0] for i in range(10000)]


#instead of


total_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循环更节省时间?


#this


f1 = map(func1, var1, var2)

arr = map(func2, f2, var3, var4)


#instead of this


arr = []

for i in range(1000):

    f1 = func1(var1(i), var2(i))

    f2 = func2(f1(i))

    arr.append(f2, var3, var4)

我的数据集很大,每个函数运行时间也很可观,所以我想尽可能减少时间。我想从根本上知道增加Python中同一循环的行数是否会增加时间。


人到中年有点甜
浏览 125回答 3
3回答

Smart猫小萌

更多代码行是否意味着性能降低的问题是有缺陷的,因为两者都不是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+1def list_comprehension(ls):    return [f(x) for x in ls]def for_loop(ls):    arr = []    for x in ls:        arr.append(f(x))    return arrdef 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}无论如何,在这种情况下最好的办法是写下所有不同的版本并自己进行分析,而不是依赖一般假设。

ibeautiful

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

白猪掌柜的

行数与代码的执行完全无关。py 文件将被读取一次、解析和编译。随后,将执行编译后的代码。换句话说,如果您创建一个包含 10 GB 空白的文件,是的,这会影响解析时间,但即使如此,执行也不会受到影响。两种变体之间的区别在于,一种使用列表理解来创建列表,而另一种则创建一个空列表,然后填充它。我的直觉是,列表理解理论上更容易优化,但如果你真的关心微小的差异,你应该分析它。另一方面,执行时间的微小差异很少会导致代码看起来更糟糕,因此默认情况下您应该始终选择更优雅的解决方案。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python