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

后端 未结 2 456
死守一世寂寞
死守一世寂寞 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

    Supplementary to Patrick's excellent answer, let's try timeit with your actual code:

    >>> def isSublist1(list1,list2):                                                                                                                                                                                                                              
    ...   for i in range(len(list2)):                                                                                                                                                                                                                             
    ...     part=list2[i:]                                                                                                                                                                                                                                        
    ...     if len(part)>> def isSublist2(list1,list2):
    ...   for i in range(len(list2)):
    ...     if len(list2[i:])>> list1=list(range(10000))
    >>> list2=list(range(4000,4020))
    >>> import timeit
    >>> timeit.timeit('isSublist1(list2,list1)', globals=globals(),number=100)
    6.420147094002459
    >>> timeit.timeit('isSublist2(list2,list1)', globals=globals(),number=100)
    12.455138996010646
    

    So on my system, the amount of time needed with your temporary variable is just about half the time needed without it.

    I don't know the nature of your lists and sublists; you may want to change what list1 and list2 are to be a good reflection of how your code will be used, but at least on my side, it looks like saving that temporary variable is a very good idea.

    Incidentally, let's do another interesting experiment:

    >>> def isSublist3(list1,list2):
    ...   ln = len(list1)
    ...   for i in range(len(list2)):
    ...     part=list2[i:]
    ...     if len(part)>> timeit.timeit('isSublist1(list2,list1)',globals=globals(),number=100); timeit.timeit('isSublist3(list2,list1)',globals=globals(),number=100)
    6.549526696035173
    6.481004184985068
    

    I ran it a few more times to see what I'd get:

    6.470875242026523 6.463623657007702

    6.151073662971612 5.787795798969455

    5.685607994964812 5.655005165026523

    6.439315696014091 6.372227535001002

    Note that each time, the cached length takes less time than the non-cached length, though you don't get nearly the performance improvement you had by caching the slicing.

    Note also that it's important not to draw too many conclusions from a single run of timeit. There are a lot of other variables affecting the timing, (in my case, pretty clearly, something happened to make it drop from 6.4 to 5.7 - in the middle of a single test!) so if you want to come up with a good rule you can count on, test several times to make sure you get consistent results.

提交回复
热议问题