2013-01-22 57 views
0

我花了整整一天等待循環退出,沒有希望!我知道python在性能方面效率並不高,因此我會非常感謝任何加速我的問題的建議。加速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用於加速嵌套循環,但老實說,我不知道如何使用我的情況。任何見解將是巨大的

+0

如果您的瓶頸所在的處理器上用Cython只會更快。看來你的瓶頸是IO相關的。在這種情況下,無論您的本機處理器處理代碼的速度如何,您的速度都不會增加。 –

+0

好吧,您正在循環查看數據包列表,獲取與當前數據包相同的第二個數據包,並將它添加到列表中。你確定你想要這樣做嗎? –

+0

你的假設是錯誤的:Python非常適合編寫出色的軟件。通常是導致軟件運行緩慢的算法。處理500k數據包絕對不需要一整天。 – Ber

回答

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

您應該注意,列表解析中的隱含循環與Cython實現會執行相同的事情:將循環執行推送到C中。 –

+0

感謝您的解決方案和闡述 – OiaSam

+0

@JoelCornett - 我對內核知之甚少,但不是因爲不必調用'append'和'LIST_APPEND'的使用而導致的速度差異? - 如果你看看'dis.dis' – root

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] 
+0

謝謝,它現在運行得更快!..感謝幫助 – OiaSam