快速转换时间戳以进行持续时间计算

时间:2017-04-04 20:08:31

标签: python performance python-2.7

我们有一个日志分析器,可以解析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分钟。

用此this question替换strptime()

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,除非有人有另一个好主意?

2 个答案:

答案 0 :(得分:3)

所以我一直在寻找,我找到了一个做得很棒的模块:

介绍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 :(得分:0)

您还可以做其他两件事(虽然不快,但是至少很方便编写代码):

create trigger trig_on_insert 
after insert on 
support_tickets
for each row
execute procedure trig_fun()