我正在学习Python中的时间分析。在指出time模块用于时序分析时,我使用了timeit模块。
我对时序分析的主要重点是对相同功能的两个变体进行多个测试用例。在这个示例代码中,我使用了两个函数变体来逆转一个数字。
时间分析能做得更好吗?该方法对于许多测试用例是可扩展的吗?
def reverse_num(num):
'''returns the reverse of an integer '''
if num < 0:
return - int(str(-num)[::-1])
else:
return int(str(num)[::-1])
def reverse_num2(num):
rev = 0
while num > 0:
rev *= 10
rev += num % 10
num /= 10
return rev
if __name__ == "__main__":
from timeit import Timer
def test(f):
for i in xrange(1000):
f(i)
print Timer(lambda: test(reverse_num)).timeit(number = 100)
print Timer(lambda: test(reverse_num2)).timeit(number = 100)我正在为我的timeit模块的使用发布示例测试运行,以便为下面的代码计时。我为这个问题写的。
def mysort(words):
mylist1 = sorted([i for i in words if i[:1] == "s"])
mylist2 = sorted([i for i in words if i[:1] != "s"])
list = mylist1 + mylist2
return list
def mysort3(words):
ans = []
p = ans.append
q = words.remove
words.sort()
for i in words[:]:
if i[0] == 's':
p(i)
q(i)
return ans + words
def mysort4(words):
ans1 = []
ans2 = []
p = ans1.append
q = ans2.append
for i in words:
if i[0] == 's':
p(i)
else:
q(i)
ans1.sort()
ans2.sort()
return ans1 + ans2
def mysort6(words):
return ( sorted([i for i in words if i[:1] == "s"]) +
sorted([i for i in words if i[:1] != "s"])
)
if __name__ == "__main__":
from timeit import Timer
def test(f):
f(['a','b','c','abcd','s','se', 'ee', 'as'])
print Timer(lambda: test(mysort)).timeit(number = 10000)
print Timer(lambda: test(mysort3)).timeit(number = 10000)
print Timer(lambda: test(mysort4)).timeit(number = 10000)
print Timer(lambda: test(mysort6)).timeit(number = 10000)计时结果如下
================================重启================================ >>> 0.0643831414457 0.0445699517515 0.0446611241927 0.0616633662243 >>> ================================重启================================ >>> 0.0625827896417 0.045101588386 0.0443568108447 0.0443568108447 ================================重新启动================================ >>> 0.0647336488305 0.0596154305912 0.0445711673841 0.0614101094441 0.06141094434 >>> ================================重新启动================================ >>> 0.0689924148581 0.0502542495475 0.0443466805735 0.0903234506 0.09001730656 0.0443794415 0.0835670386907 en20 20 en22#0.06756121379 0.050799814 0.04417814 0.04417854 0.068103000978 en20 20 0.06756121379 0.050799814 0.04417814 0.0681030978
正如您所看到的,结果每次都不同。我知道时间很小,但这是number = 10000在timeit中的全部目的,就是通过多次计时和寻找平均或最好的时间来持续地进行测量。
在大多数情况下,第二个函数比第三个函数要花费更多的时间,但有时不需要。在某些情况下,第四个函数比第一个函数花费更多的时间,有时更少。
我认为这是正确的,根据使用,但为什么这些变量的结果?这是做时间安排的正确方法吗?我真的很困惑。
经过聊天室的一些讨论和一些思考之后,我想出了测试具有整数输入的函数的方法。可以为更多的测试定义额外的嵌套函数,并且可以进行更多的重复。这可能需要一段时间,但据我所知,效果很好。对于同一个函数的变体,需要添加简单的函数调用。
def testing():
from timeit import Timer
import random
def tests(f, times):
def test1(f):
f(random.randint(1, 1000))
def test2(f):
f(random.randint(100000, 1000000))
print(f.__name__)
print(Timer(lambda: test1(f)).timeit(number = times))
print(Timer(lambda: test2(f)).timeit(number = times//10))
print()
tests(reverse_num, 10000)
tests(reverse_num2, 10000)请注意,我是在讨论这个问题时开始使用Python 3的。我不会使用任何特定于Python 3的代码,所以所有代码都可以在Python2上运行,任何想要运行新代码的人只需更改print语句即可。没别的了。
发布于 2013-07-18 05:43:31
软件定时基准是出了名的噪音,因为你的计算机不是一个很好的控制实验平台。
我会怀疑我给出的效果是按强度递减的顺序给出的(除了我相信Python的排序算法是确定性的,所以第一个效果不是这里的一个因素)。我还怀疑我只是擦破了表面。
好的,为了逆转一个数字,假设您的典型输入是5位,那么您可以使用它。
if __name__ == "__main__":
from timeit import Timer
import random
def test(f):
f(random.randint(10000,99999))
print Timer(lambda: test(reverse_num)).timeit(number = 10000000)
print Timer(lambda: test(reverse_num2)).timeit(number = 10000000)https://codereview.stackexchange.com/questions/28373
复制相似问题