這是我對代碼的第一次優化,我很興奮。閱讀一些文章,但我仍然有一些問題。在Python中使用pstats和cProfile。如何使陣列工作更快?
1)首先,下面我的代碼花了那麼多時間?我認爲這是數組在這裏:array.append(len(set(line.split())))。我在網上閱讀,Python中的列表工作得更快,但我沒有看到在這裏使用列表。有人知道如何改進?
2)有沒有其他改進我失蹤?
3)另外,網上說它for循環減慢代碼很多。這裏可以改進嗎? (我猜在C編寫的代碼是最好的,但是:D)
4)爲什麼人們建議總是看「ncalls」和「tottime」?對我而言,「percall」更有意義。它告訴你你的功能或通話有多快。
5)在這裏的正確答案B類他申請名單。他呢?對我來說,我仍然可以看到一個數組和一個FOR循環,它可以減慢速度。 Fastest way to grow a numpy numeric array
謝謝。
NEW CPROFILE結果:
618384 function calls in 9.966 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
19686 3.927 0.000 4.897 0.000 <ipython-input-120-d8351bb3dd17>:14(f)
78744 3.797 0.000 3.797 0.000 {numpy.core.multiarray.array}
19686 0.948 0.000 0.948 0.000 {range}
19686 0.252 0.000 0.252 0.000 {method 'partition' of 'numpy.ndarray' objects}
19686 0.134 0.000 0.930 0.000 function_base.py:2896(_median)
1 0.126 0.126 9.965 9.965 <ipython-input-120-d8351bb3dd17>:22(<module>)
19686 0.125 0.000 0.351 0.000 _methods.py:53(_mean)
19686 0.120 0.000 0.120 0.000 {method 'reduce' of 'numpy.ufunc' objects}
19686 0.094 0.000 4.793 0.000 function_base.py:2747(_ureduce)
19686 0.071 0.000 0.071 0.000 {method 'flatten' of 'numpy.ndarray' objects}
19686 0.065 0.000 0.065 0.000 {method 'format' of 'str' objects}
78744 0.055 0.000 3.852 0.000 numeric.py:464(asanyarray)
NEW CODE:
import numpy
import cProfile
pr = cProfile.Profile()
pr.enable()
#paths to files
read_path = '../tweet_input/tweets.txt'
write_path = "../tweet_output/ft2.txt"
def f(a):
for i in range(0, len(array)):
if a <= array[i]:
array.insert(i, a)
break
if 0 == len(array):
array.append(a)
try:
with open(read_path) as inf, open(write_path, 'a') as outf:
array = []
#for every line (tweet) in the file
for line in inf: ###Loop is bad. Builtin function is good
#append amount of unique words to the array
wordCount = len(set(line.split()))
#print wordCount, array
f(wordCount)
#write current median of the array to the file
result = "{:.2f}\n".format(numpy.median(array))
outf.write(result)
except IOError as e:
print 'Operation failed: %s' % e.strerror
###Service
pr.disable()
pr.print_stats(sort = 'time')
OLD CPROFILE結果:在13.195秒 由有序 551211函數調用:內部時刻
ncalls tottime percall cumtime percall文件名:lineno(功能) 78744 10.193 0.0 00 10.193 0.000 {numpy.core.multiarray.array}
OLD CODE:
with open(read_path) as inf, open(write_path, 'a') as outf:
array = []
#for every line in the file
for line in inf:
#append amount of unique words to the array
array.append(len(set(line.split())))
#write current median of the array to the file
result = "{:.2f}\n".format(numpy.median(array))
outf.write(result)
您是否基於cProfile輸出做出了這個結論?如果是的話,你怎麼看?這條線是唯一暗示爲什麼需要這麼長時間的「numpy.core.multiarray.array」。但它沒有提及任何有關中位數函數的內容。 – Sergey
中位數函數是numpy庫的一部分。 cProfile中的{numpy.core.multiarray.array}是在numpy庫中花費在* everything *上的時間。我做出了結論,因爲你只有一次調用你的循環中的'numpy'庫函數 - 調用'numpy.median'。 您可以通過在新函數中將調用包裝爲'median'來查看,並在cProfile中查看在該函數中花費的'tottime'。 – James
哼!很有意思。我在數組中實現了排序插入。現在運行代碼的總時間從11.873降至9.966。我會在上面發佈我的新解決方案。看起來我在{numpy.core.multiarray.array}上的代碼花費了3.797和9.309秒,但是我創建的函數又花了3.927秒。因此3.797 + 3.927 = 7.724秒。這是一樣的。難道我做錯了什麼? – Sergey