Should I store a calculation in a variable if it will be used a lot?

后端 未结 2 454
死守一世寂寞
死守一世寂寞 2021-01-22 00:42

If I have a function to, for example, check if list1 is a sublist of list2, which option is better:

Option 1:



        
2条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-22 01:18

    Storing local is better because the lookup that python does is faster. It even pays off to store functions locally.

    Performance questions are best answered by timing them - you can measure this using timeit:

    import timeit
    
    def noTempFunc():
        for _ in range(200):
            max([1,4,5,6])
    
    def tempFunc():
        m = max
        for _ in range(200):
            m([1,4,5,6])
    
    
    print(timeit.timeit(noTempFunc, number=1000))   #  0.055301458000030834
    print(timeit.timeit(tempFunc, number=1000))     #  0.049811941999905684 : 11% faster
    

    In this case the max() of the global context only has to be looked up once, and further lookups are done locally which is ~ 11% faster based on these numbers.

    It pays up if you use your local m() multiple times.


    In your case it would be sensible to cache the len_list1 = len(list1) - as it is used lots of time and does not change.

    To make it more readable, you can consider:

    def isSublist(list1, list2):
        """Checks if list2 is a sublist of list1"""
        len_part = len(list2)  # reused inside the list comp, only "calulated" once
        return any( x == list2 for x in (list1[i:i+len_part] 
                                         for i in range(len(list1)-len_part+1) ))
    
    
    print(isSublist([1,2,3,4],[1]))
    print(isSublist([1,2,3,4],[2,3]))
    print(isSublist([1,2,3,4],[1,2,4]))
    print(isSublist([1,2,3,4],[1,2,3,4]))
    

    Output:

    True
    True
    False
    True
    

    Lookups:

    • any() && How exactly does the python any() function work?
    • Split a python list into other "sublists" i.e smaller lists

    Your faster version with cached length as well (based on Scott Mermelstein answer):

    def isSublist1a(list1,list2): # cached length as well
        l1 = len(list1)
        for i in range(len(list2)):
            part=list2[i:]
            if len(part)

    delivers (2 executions):

    0.08652938600062043  # cached part
    0.08017484299944044  # cached part + cached list1 lenght - slightly faster
    0.15090413599955355  # non-cached version
    
    0.8882850420004615   # cached part
    0.8294611960000111   # cached part + cached list1 lenght - slightly faster
    1.5524438030006422   # non-cached version
    

提交回复
热议问题