加速python循环处理数据包

时间:2013-01-22 10:34:11

标签: python performance cython scapy

我花了一整天等待一个循环,没有希望退出!我知道python在性能方面不是那么高效,我真的很感激任何加速建议来解决我的问题。

我使用wireshark捕获了大量数据包(大约500,000个)并将它们保存到.pcap文件中。之后,我使用Scapy rdpcap()函数从保存的文件中读取数据包,然后在循环中访问每个数据包以提取源IP地址。我的代码如下:

from scaly.all import *

srcList =[]
Packets = rdpcap("pcapfile")

for pkt in Packets:
    src = Packets[Packets.index(pkt)][1].src
    srcList.append(src)

注意:我已经做了一些挖掘,我发现Cython用于加速嵌套循环,但老实说我不知道​​如何在我的情况下使用它。任何见解都会很棒

3 个答案:

答案 0 :(得分:6)

如果我没有误解你的意图,你可以简化你的代码,这也应该加快它的速度:

from scaly.all import *

Packets = rdpcap("pcapfile")
srcList = [pkt[1].src for pkt in Packets]

这个解决方案与您的解决方案之间的区别可以用一个简单的例子来说明。如您所见,第二个功能的速度提高了10倍以上。

In [1]: lst = range(100)

In [2]: def f1(lst):
   ...:     out = []
   ...:     for item in lst:
   ...:         out.append(lst[lst.index(item)])
   ...:     return out

In [3]: def f2(lst):
   ...:     return [item for item in lst]

In [4]: %timeit f1(lst)
1000 loops, best of 3: 221 us per loop

In [5]: %timeit f2(lst)
100000 loops, best of 3: 9.61 us per loop

答案 1 :(得分:4)

我怀疑问题出在行src = Packets[Packets.index(pkt)][1].src,因为循环为O(n),列表搜索为O(n),使其成为O(n**2)

也许以下内容也可以起作用:

from scaly.all import *

srcList =[]
Packets = rdpcap("pcapfile")

for pkt in Packets:
    src = pkt[1].src
    srcList.append(src)

from scaly.all import *

Packets = rdpcap("pcapfile")
srcList = [pkt[1].src for pkt in Packets]

答案 2 :(得分:0)

如果您只想获取IP来源,请告诉scapy忽略解析IP层之后的任何内容的方法:

IP.payload_guess = []

在致电rdpcap之前将其放置。 Scapy花大量时间遍历每一层,解析并提取所有可以找到的内容。这是大部分时间用于读取数据包的地方。

此外,请考虑将rdpcap的{​​{1}}更改为不会加载整个文件。这样不一定能加快速度,但可以减少内存占用。