Are list-comprehensions and functional functions faster than “for loops”?

后端 未结 7 1610
梦如初夏
梦如初夏 2020-11-22 01:48

In terms of performance in Python, is a list-comprehension, or functions like map(), filter() and reduce() faster than a for loop? Why

7条回答
  •  我寻月下人不归
    2020-11-22 02:06

    I modified @Alisa's code and used cProfile to show why list comprehension is faster:

    from functools import reduce
    import datetime
    
    def reduce_(numbers):
        return reduce(lambda sum, next: sum + next * next, numbers, 0)
    
    def for_loop(numbers):
        a = []
        for i in numbers:
            a.append(i*2)
        a = sum(a)
        return a
    
    def map_(numbers):
        sqrt = lambda x: x*x
        return sum(map(sqrt, numbers))
    
    def list_comp(numbers):
        return(sum([i*i for i in numbers]))
    
    funcs = [
            reduce_,
            for_loop,
            map_,
            list_comp
            ]
    
    if __name__ == "__main__":
        # [1, 2, 5, 3, 1, 2, 5, 3]
        import cProfile
        for f in funcs:
            print('=' * 25)
            print("Profiling:", f.__name__)
            print('=' * 25)
            pr = cProfile.Profile()
            for i in range(10**6):
                pr.runcall(f, [1, 2, 5, 3, 1, 2, 5, 3])
            pr.create_stats()
            pr.print_stats()
    

    Here's the results:

    =========================
    Profiling: reduce_
    =========================
             11000000 function calls in 1.501 seconds
    
       Ordered by: standard name
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      1000000    0.162    0.000    1.473    0.000 profiling.py:4(reduce_)
      8000000    0.461    0.000    0.461    0.000 profiling.py:5()
      1000000    0.850    0.000    1.311    0.000 {built-in method _functools.reduce}
      1000000    0.028    0.000    0.028    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    
    
    =========================
    Profiling: for_loop
    =========================
             11000000 function calls in 1.372 seconds
    
       Ordered by: standard name
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      1000000    0.879    0.000    1.344    0.000 profiling.py:7(for_loop)
      1000000    0.145    0.000    0.145    0.000 {built-in method builtins.sum}
      8000000    0.320    0.000    0.320    0.000 {method 'append' of 'list' objects}
      1000000    0.027    0.000    0.027    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    
    
    =========================
    Profiling: map_
    =========================
             11000000 function calls in 1.470 seconds
    
       Ordered by: standard name
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      1000000    0.264    0.000    1.442    0.000 profiling.py:14(map_)
      8000000    0.387    0.000    0.387    0.000 profiling.py:15()
      1000000    0.791    0.000    1.178    0.000 {built-in method builtins.sum}
      1000000    0.028    0.000    0.028    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    
    
    =========================
    Profiling: list_comp
    =========================
             4000000 function calls in 0.737 seconds
    
       Ordered by: standard name
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      1000000    0.318    0.000    0.709    0.000 profiling.py:18(list_comp)
      1000000    0.261    0.000    0.261    0.000 profiling.py:19()
      1000000    0.131    0.000    0.131    0.000 {built-in method builtins.sum}
      1000000    0.027    0.000    0.027    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    
    

    IMHO:

    • reduce and map are in general pretty slow. Not only that, using sum on the iterators that map returned is slow, compared to suming a list
    • for_loop uses append, which is of course slow to some extent
    • list-comprehension not only spent the least time building the list, it also makes sum much quicker, in contrast to map

提交回复
热议问题