我正在做一个有三个功能的速度测试,readFile,prepDict和test。测试是简单的predict(readFile)。然后我用timeit模块运行了很多次。你知道吗
当我将循环的数量增加10倍时,函数prepDict花费的时间大约是原来的100倍,而使用函数prepDict的函数测试只增加了10倍。你知道吗
下面是函数和测试。你知道吗
def readFile(filepath):
tempDict = {}
file = open(filepath,'rb')
for line in file:
split = line.split('\t')
tempDict[split[1]] = split[2]
return tempDict
def prepDict(tempDict):
for key in tempDict.keys():
tempDict[key+'a'] = tempDict[key].upper()
del tempDict[key]
return tempDict
def test():
prepDict(readFile('two.txt'))
if __name__=='__main__':
from timeit import Timer
t = Timer(lambda: readFile('two.txt'))
print 'readFile(10000): ' + str(t.timeit(number=10000))
tempDict = readFile('two.txt')
t = Timer(lambda: prepDict(tempDict))
print 'prepDict (10000): ' + str(t.timeit(number=10000))
t = Timer(lambda: test())
print 'prepDict(readFile) (10000): ' + str(t.timeit(number=10000))
t = Timer(lambda: readFile('two.txt'))
print 'readFile(100000): ' + str(t.timeit(number=100000))
tempDict = readFile('two.txt')
t = Timer(lambda: prepDict(tempDict))
print 'prepDict (100000): ' + str(t.timeit(number=100000))
t = Timer(lambda: test())
print 'prepDict(readFile) (100000): ' + str(t.timeit(number=100000))
我得到的结果如下:
readFile(10000): 0.61602914474
prepDict (10000): 0.200615847469
prepDict(readFile) (10000): 0.609288647286
readFile(100000): 5.91858320729
prepDict (100000): 18.8842101717
prepDict(readFile) (100000): 6.45040039665
如果我多次运行它,就会得到类似的结果。为什么prepDict增加了约100倍,而prepDict(readFile)只增加了10倍,即使它使用prepDict函数?你知道吗
你知道吗两个.txt是具有以下数据点的表格分隔文件:
Item Title Hello2
Item Desc Testing1232
Item Release 2011-02-03
对
prepDict
的调用不是在孤立的环境中发生的。每次对prepDict
的调用都会修改tempDict
键,每次都会变长一点。因此,在对prepDict
进行10**5次调用之后,prepDict
中的键是相当大的字符串。如果将print语句放在prepDict
中,您可以(大量地)看到这一点:解决这个问题的方法是确保每次调用
prepDict
或者更一般地说,您正在计时的语句不会影响正在计时的下一个调用(或语句)。abarnert已经展示了解决方案:prepDict(tempDict.copy())
。你知道吗顺便说一下,您可以使用
for-loop
来减少代码重复:产生计时,例如
之所以会发生这种情况,是因为当您只测试
prepDict
时,您正在为所有对prepDict
的调用重用tempDict
。由于prepDict
在字典中的所有项上循环,然后基本上只是将每个字符串键的长度增加一个,最终会得到一堆非常长的键。随着它的发展,这开始减慢您的函数的速度,因为字符串连接操作正在使用/重新创建越来越大的字符串。你知道吗这在
test
中不是问题,因为每次都要重新初始化字典。你知道吗这里的问题是
prepDict
函数扩展了输入。每次按顺序调用它时,它都有更多的数据要处理。数据呈线性增长,因此第10000次运行的时间大约是第一次运行的10000倍。*当您调用
test
时,它每次都在创建一个新的dict,因此时间是恒定的。你知道吗通过更改
prepDict
测试以每次在dict的新副本上运行,您可以很容易地看到这一点:顺便说一下,你的
prepDict
实际上并不是随着number
呈指数增长的,只是二次增长。一般来说,当某个数据呈超线性增长时,您需要估计算法开销,您确实需要获得两个以上的数据点。你知道吗*这不是真的,它只会在字符串和散列操作(线性增长)所花费的时间开始淹没每一个其他操作(都是常数)所花费的时间时开始线性增长。你知道吗
**您在这里没有提到任何关于指数增长的内容,但在your previous question中您提到了,因此您可能在实际问题中做出了相同的毫无根据的假设。你知道吗
相关问题 更多 >
编程相关推荐