2017-04-04 124 views
2

我們有一個日誌分析器,用於解析100GB數量級的日誌(我的測試文件約爲2000萬行,1.8GB)。它花費的時間比我們想(向上半天),所以我跑了反對CPROFILE和時間> 75%正在採取strptime:用於持續時間計算的時間戳快速轉換

 1 0.253 0.253 560.629 560.629 <string>:1(<module>) 
20000423 202.508 0.000 352.246 0.000 _strptime.py:299(_strptime) 

計算日誌條目之間的持續時間,目前爲:

ltime = datetime.strptime(split_line[time_col].strip(), "%Y-%m-%d %H:%M:%S") 
lduration = (ltime - otime).total_seconds() 

其中otime是從上一行

日誌文件的線沿線的格式化時間戳:

0000 | 774 | 475  | 2017-03-29 00:06:47 | M  |  63 
0001 | 774 | 475  | 2017-03-29 01:09:03 | M  |  63 
0000 | 774 | 475  | 2017-03-29 01:19:50 | M  |  63 
0001 | 774 | 475  | 2017-03-29 09:42:57 | M  |  63 
0000 | 775 | 475  | 2017-03-29 10:24:34 | M  |  63 
0001 | 775 | 475  | 2017-03-29 10:33:46 | M  |  63  

對測試文件運行它需要將近10分鐘。

更換strptime()與此(從this question):

def to_datetime(d): 
    ltime = datetime.datetime(int(d[:4]), 
           int(d[5:7]), 
           int(d[8:10]), 
           int(d[11:13]), 
           int(d[14:16]), 
           int(d[17:19])) 

帶來下來到剛剛超過3分鐘。

CPROFILE再次報告:

 1 0.265 0.265 194.538 194.538 <string>:1(<module>) 
20000423 62.688 0.000 62.688 0.000 analyzer.py:88(to_datetime) 

這種轉換仍需要大約時間爲整個分析儀運行的三分之一。內嵌將轉換佔用空間減少了大約20%,但我們仍然在尋找25%的時間來處理這些行將時間戳轉換爲datetime格式(其中total_seconds()在此之上消耗另外約5%)。

我可能最終只寫一個自定義時間戳到秒轉換完全繞過datetime,除非有人有另一個好主意?

+0

你是否檢查過這3分鐘中有多少時間用於實例化'''datetime'''一次又一次,不解析數據? ;)我不確定是否可以在不改變方法本身的情況下進一步提升它......像多處理或者簡單地不爲每行創建一個「datetime」。 – Art

+0

你有沒有考慮[多處理塊](https://docs.python.org/2/library/multiprocessing.html#multiprocessing.pool.multiprocessing.Pool.map)? –

+0

@藝術〜25%的時間花在解析和實例化日期時間對象上,這就是問題所在。 – TemporalWolf

回答

2

所以我一直在尋找,我已經找到了一個模塊,做了出色的工作:

介紹ciso8601

from ciso8601 import parse_datetime 
... 
ltime = parse_datetime(sline[time_col].strip()) 

其中,通過CPROFILE:

 1 0.254 0.254 123.795 123.795 <string>:1(<module>) 
20000423 4.188 0.000 4.188 0.000 {ciso8601.parse_datetime} 

這是〜比通過datetime.strptime() ......的天真方法快84倍......這並不令人驚訝,因爲它們是wrote a C module to do it

+1

'''因爲它被寫成C模塊,所以速度要快得多......'':D – Art

+0

顯然,如果你的字符串表示是ISO,並且你可以在你的平臺上編譯這個模塊,那麼這是一個很好的解決方案。並不是每個人都在這個問題上磕磕絆絆,這種情況一定會發生。不過,這是一個很好的發現,可能對大多數人有用。 –

+0

@JohnY鑑於性能的不穩定性,即使您必須首先將字符串轉換爲ISO8601,如果它不能擊敗大多數其他方法,我會感到驚訝。 – TemporalWolf