加快python循环处理数据包的速度

加快python循环处理数据包的速度,python,performance,cython,scapy,Python,Performance,Cython,Scapy,我花了一整天的时间等待一个循环毫无希望地退出!。我知道python在性能方面并没有那么有效,因此我非常感谢对我的问题提出任何加速建议 我使用wireshark捕获了大量数据包(大约500000个),并将它们保存到.pcap文件中。之后,我使用Scapy rdpcap()函数从保存的文件中读取数据包,然后在循环中访问每个数据包以提取源IP地址。我的代码如下: from scaly.all import * srcList =[] Packets = rdpcap("pcapfile") for

我花了一整天的时间等待一个循环毫无希望地退出!。我知道python在性能方面并没有那么有效,因此我非常感谢对我的问题提出任何加速建议

我使用wireshark捕获了大量数据包(大约500000个),并将它们保存到.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用于加速嵌套循环,但老实说,我不知道如何在我的例子中使用它。如果我没有误解您的意图,您可以简化您的代码,这也会加快速度:

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

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

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

我怀疑问题出在行
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)


我怀疑问题出在行
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)


如果您只需要IP源,请告诉scapy忽略解析IP层之后的任何内容,方法是:

IP.payload_guess = []
将其置于调用
rdpcap
之前。Scapy花了很多时间浏览每一层,解析和提取它能找到的所有内容。这是大部分时间用来阅读数据包的地方


也可以考虑更改<代码> RDPCAP<代码> > <代码> PcapReader <代码>,它不加载整个文件。这不一定会加快速度,但会减少内存占用。

如果您只需要IP源,请告诉scapy忽略解析IP层之后的任何内容,方法是:

IP.payload_guess = []
将其置于调用
rdpcap
之前。Scapy花了很多时间浏览每一层,解析和提取它能找到的所有内容。这是大部分时间用来阅读数据包的地方


也可以考虑更改<代码> RDPCAP<代码> > <代码> PcapReader <代码>,它不加载整个文件。这不一定会加快速度,但会减少内存占用。

Cython只有在瓶颈位于处理器上时才会更快。您的瓶颈似乎与IO相关。在这种情况下,无论您的本机处理器处理代码的速度有多快,您的速度都不会提高。好吧,您正在一个数据包列表上循环,获取与当前数据包等效的第二个数据包,并将其添加到列表中。您确定要这样做吗?您的假设是错误的:Python非常适合编写性能优异的软件。通常是算法导致软件运行缓慢。处理500k个数据包肯定不需要花一整天的时间。我怀疑问题出在线路上
src=packets[packets.index(pkt)][1]。src
,因为循环是
O(n)
,列表搜索是
O(n)
使它成为
O(n**2)
@JoelCornett感谢Scython指出,只有当瓶颈位于处理器上时,Scython才会更快。您的瓶颈似乎与IO相关。在这种情况下,无论您的本机处理器处理代码的速度有多快,您的速度都不会提高。好吧,您正在一个数据包列表上循环,获取与当前数据包等效的第二个数据包,并将其添加到列表中。您确定要这样做吗?您的假设是错误的:Python非常适合编写性能优异的软件。通常是算法导致软件运行缓慢。处理500k个数据包肯定不需要花一整天的时间。我怀疑问题出在线路上
src=packets[packets.index(pkt)][1]。src
,因为循环是
O(n)
,列表搜索是
O(n)
使它成为
O(n**2)
@JoelCornett感谢地指出您应该注意,列表理解中的隐含循环与Cython实现的作用相同:将循环执行推入C。感谢您的解决方案和elaboration@JoelCornett--我对内部不太了解,但是速度差异不是由不必调用
append
和使用
LIST\u append
引起的吗如果你看
dis.dis
速度差来自O(n**2)v。算法中的O(n)。谁编写循环并不重要。@Ber--你是对的。差异的增加只在非常小的列表中出现(删除该示例)。因此,这似乎是一个设置问题——但仍然不确定确切的原因。您应该注意,列表理解中的隐含循环与Cython实现的作用相同:将循环执行推进C。感谢您的解决方案和elaboration@JoelCornett--我对内部不太了解,但是速度差异不是由不必调用
append
和使用
LIST\u append
引起的吗如果你看
dis.dis
速度差来自O(n**2)v。算法中的O(n)。谁编写循环并不重要。@Ber--你是对的。差异的增加只在非常小的列表中出现(删除该示例)。因此,这似乎是一个设置的东西-仍然不确定到底为什么。