简体   繁体   English

定时功能

[英]Timing functions

Warning, this is a bit recursive ;) 警告,这有点递归;)

I answered this question: Python:How can i get all the elements in a list before the longest element? 我回答了这个问题: Python:如何在最长元素之前获取列表中的所有元素?

And after I submitted there where another answer that should be faster (the author thought, and so did I). 在我提交之后,另一个应该更快的答案(作者认为,我也是如此)。 I tried to time the different solutions but the solution that should be slower was actually faster. 我试图计算不同的解决方案,但应该更慢的解决方案实际上更快。 This made me think there is something wrong with my code. 这让我觉得我的代码有问题。 Or is it? 或者是吗?

import string
import random
import time

def solution1(lst):
  return lst[:lst.index(max(lst, key=len))]

def solution2(lst):
  idx, maxLenStr = max(enumerate(lst), key=lambda x:len(x[1]))
  return lst[:idx]

# Create a 100000 elements long list that contains
# random data and random element length
lst = []
for i in range(100000):
  s = "".join([random.choice(string.letters+string.digits) for x in range(1, random.randint(1,50))])
  lst.append(s)

# Time the first solution
start = time.time()
solution1(lst)
print 'Time for solution1', (time.time() - start)

# Time the second solution
start = time.time()
solution2(lst)
print 'Time for solution2', (time.time() - start)

Update 更新

Before anyone mentions why I put this is as a new question. 在任何人提到我之前为什么这是一个新问题。 The question is more about me learning how to measure execution time... 问题更多是关于我学习如何衡量执行时间......

It seems first version is making many less calls than the second one. 似乎第一个版本的呼叫次数少于第二个版本。

btw, This is probably another example of how idiomatic, simple code is often also the faster one in Python 顺便说一句,这可能是另一个例子,说明惯用的,简单的代码通常也是Python中更快的代码

>>> dis.dis(solution1)
  2           0 LOAD_FAST                0 (lst)
              3 LOAD_FAST                0 (lst)
              6 LOAD_ATTR                0 (index)
              9 LOAD_GLOBAL              1 (max)
             12 LOAD_FAST                0 (lst)
             15 LOAD_CONST               1 ('key')
             18 LOAD_GLOBAL              2 (len)
             21 CALL_FUNCTION          257
             24 CALL_FUNCTION            1
             27 SLICE+2             
             28 RETURN_VALUE        
>>> dis.dis(solution2)
  2           0 LOAD_GLOBAL              0 (max)
              3 LOAD_GLOBAL              1 (enumerate)
              6 LOAD_FAST                0 (lst)
              9 CALL_FUNCTION            1
             12 LOAD_CONST               1 ('key')
             15 LOAD_CONST               2 (<code object <lambda> at 000000000422BEB8, file "<input>", line 2>)
             18 MAKE_FUNCTION            0
             21 CALL_FUNCTION          257
             24 UNPACK_SEQUENCE          2
             27 STORE_FAST               1 (idx)
             30 STORE_FAST               2 (maxLenStr)

  3          33 LOAD_FAST                0 (lst)
             36 LOAD_FAST                1 (idx)
             39 SLICE+2             
             40 RETURN_VALUE 

The lambda is costing dearer in the second solution. 在第二种解决方案中,lambda的成本更高。

I profiled both the codes and by the profile data, it looks, the first solution is faster 我分析了代码和配置文件数据,看起来,第一个解决方案更快

As the wiki would say function call is costly and in the second solution, the lambda and the len function calls are making it run slower 由于wiki会说函数调用成本很高,而在第二个解决方案中,lambda和len函数调用使它运行得更慢

Please note, I have trimmed down the list to a length of 1000 elements 请注意,我已将列表缩减为1000个元素的长度

>>> cProfile.run('solution1(lst)')
         5 function calls in 0.000 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 <pyshell#305>:1(solution1)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000 {max}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.000    0.000    0.000    0.000 {method 'index' of 'list' objects}


>>> cProfile.run('solution2(lst)')
         2004 function calls in 0.012 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.012    0.012 <pyshell#306>:1(solution2)
     1000    0.006    0.000    0.009    0.000 <pyshell#306>:2(<lambda>)
        1    0.000    0.000    0.012    0.012 <string>:1(<module>)
     1000    0.003    0.000    0.003    0.000 {len}
        1    0.003    0.003    0.012    0.012 {max}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

The timing looks ok. 时机看起来不错。

solution1 can be faster, because it doesn't use lambdas, so it doesn't need to call Python code in the loop. solution1可以更快,因为它不使用lambda,所以它不需要在循环中调用Python代码。 It does iterate the list twice, but it's not a big deal. 它确实迭代了两次列表,但这并不是什么大问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM