求一个关于日期时间间隔计算相关的算法,具体问题如下:
当前有一个比较大(上万个)日期时间的list(时间递增但无规律),假设 dt=[
'2015-01-02 10:21:02',
'2015-01-02 10:21:02'
'2015-01-02 10:21:03'
'2015-01-02 10:21:04'
'2015-01-02 10:21:06'
'2015-01-02 10:21:10'
'2015-01-02 10:21:11'
'2015-01-02 10:21:13'
'2015-01-02 10:22:00'
'2015-01-02 10:22:12'
... ...
]
给定一个时间间隔timeframe(假设4s),现在问题是:求在给定连续时间间隔内,list中最多项数目。
最简单的方法是依次对于list中每个项x,向后查找直至大于timeframe+x的项并统计个数。但由于这个list数量庞大,同时还要涉及时间运算,算法难以达到要求,特来请教!
先給出我的答案:
上述的 code 要記得 import
datetime
和timedelta
.這是一個 O(n) 的做法, n 為
timestrs
的數量.code 有點醜, 晚一點再修, 不過為了比較速度跟正確性, 我做了一些實驗, 以下是我用來做實驗完整的 code:
包含了
一個很陽春用來計時的 decorator:
simpletimer
他會裝飾
func
, 印出執行所花的時間一個產生隨機測資的 function:
gentimestrs
他會產生
count
筆 time strings 測資, 且各資料的時間間隔是小於等於delta
的隨機整數接下來的
findmax
和findmax2
分別是我的做法跟 @citaret 的做法 (有興趣的大家可以自行仿照介面加入自己的 function, 題主也可以把自己原先的做法拿來比比看), 並且用simpletimer
計時.測試的時候先產生測資, 再分別執行
funclst
中要比較的 funcion執行的範例如下:
這邊列出一些結果:
用
timeframe==5
測試測資數量 1000, 10000, 100000用
timeframe==10
測試測資數量 1000, 10000, 100000若維持 timeframe 大小不變, 兩者的時間對測資數量都呈現線性成長
可是當 timeframe 變成兩倍時, 第二種做法的時間也會多一倍
這表示 @citaret 大的方法複雜度應該是 O(n * timeframe)
還有一點就是有時候這兩個做法的結果不太相同, 會差一, 題主若有方法可以驗證一下正確性
我單單看我找出來的答案似乎沒錯, 但若有疏忽還請大家指正我, 謝謝!
也歡迎更多人討論這題.
我回答過的問題: Python-QA
没有数据,不好 profile,先给出一版,看看别人是不是有更好的处理。
@dokelung 使用citaret算法测试了下,对于共27505个元素的list(从有63万行单个日志文件中提取,多个源ip汇总)耗时3.8842415850296845s,我原来时耗时16.544873371035163s,效率提升不少,虽然数量级还在秒,但这仅仅是一天的一个文件。同时帮我发现效率问题更严重的其实是在函数内部对满足要求日志行的提取上,感谢大家的回答与参与,谢谢!