为什么python XML解析速度不一致?

WoJ*_*WoJ 6 python xml performance parsing

我正在解析一个大的(12 GB)XML文件,该文件由大约135k或多或少类似的记录组成(这是一个nmap转储).我注意到解析速度不一致,解析类似记录的时间变化很大.

以下按比例缩小的代码输出解析每1%记录所需的时间:

from xml.etree.ElementTree import iterparse
import time
nrhosts = 0
previous = time.time()
context = iterparse("test.xml", events=("start", "end"))
context = iter(context)
event, root = context.next()
for event, elem in context:
    if event == 'end' and elem.tag == "host":
        root.clear()   # clean up memory
        nrhosts += 1
        if nrhosts % 1349 == 0:  # hardcoded to estimate the % as there are ~135k of records
            now = time.time()
            print nrhosts // 1349, now - previous  
            previous = now
Run Code Online (Sandbox Code Playgroud)

这给出了:

1 2.43700003624
2 3.13999986649
3 2.87700009346
4 2.59200000763
5 65.8800001144
6 47.6069998741
7 43.6809999943
8 29.7590000629
9 11.8629999161
10 4.52200007439
11 40.0160000324
12 42.2109999657
13 45.9930000305
14 29.1139998436
15 6.18600010872
16 41.7149999142
17 40.3410000801
18 40.0460000038
19 30.2319998741
20 1.45700001717
21 5.35100007057
22 15.4260001183
23 32.7389998436
24 42.7220001221
25 10.4960000515
26 1.28299999237
27 7.33299994469
28 22.7130000591
29 27.3199999332
30 34.4129998684
31 1.71200013161
32 1.63499999046
33 7.06900000572
34 24.1480000019
35 25.7660000324
36 20.8759999275
37 1.29399991035
38 1.34899997711
39 5.71700000763
40 35.9170000553
41 33.8300001621
42 8.69299983978
43 1.35500001907
44 1.3180000782
45 8.44099998474
46 26.1540000439
47 28.768999815
48 5.91400003433
49 1.63499999046
50 1.30800008774
51 5.93499994278
Run Code Online (Sandbox Code Playgroud)

这个输出看起来令人惊讶地"波浪":

令人惊讶的波浪形http://i.minus.com/ibiIth8t2AFf4t.png:

我想强调一点:

  • 代码运行的机器是安静的(没有什么特别的事情会干扰解析).我在运行Win7的笔记本电脑和运行Debian的ESX上的VM上有类似的结果(类似于解析速度变化很大的意义)
  • 记录大致相同:XML文件是输出,nmap -O因此每条记录的信息量(<host>在我的情况下为a )或多或少相同.我想说的是XML输出中没有任何内容可以使某些部分"更长"来解析.

我的代码中的任何内容都会暗示这种行为吗?(我使用SAX来处理XML文件的大小,也许有一些固有的东西可以修改解析速度?).

我的目标是最终了解"这是生命",只是接受事实或修改我的代码.

谢谢.

Jav*_*ier 0

这张图几乎就是缓存系统的指纹!:-) 您以块的形式读取文件(如 ElementTree 实现中所定义),但计算机在假设您很快将需要下一个块的情况下读取更多内容。这意味着您处理的下一个块将需要更少的时间,因为它已经在内存中等等。然而,在某个时刻,内存中的缓冲区将几乎为空。就在此时,您将需要“等待”一段时间才能读取下一个块,从而增加您的测量值。