2017-04-04 137 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