Ich muss lesen und analysieren. Pcap-Dateien, die zu groß sind, um in den Speicher geladen werden. Ich bin derzeit sniff im Offline-ModusWie scapy Leistung zu verbessern, große Dateien zu lesen
sniff(offline=file_in, prn=customAction, store=0)
mit einer Custom Funktion, die in etwa wie folgt aussieht:
customAction(packet):
global COUNT
COUNT = COUNT + 1
# do some other stuff that takes practically 0 time
Derzeit wird diese Pakete verarbeitet zu langsam. Ich benutze bereits Subprozess in einem 'Treiber' Programm, um dieses Skript auf mehreren Dateien gleichzeitig auf verschiedenen Kernen laufen zu lassen, aber ich muss wirklich die Single-Core-Leistung verbessern.
Ich versuchte mit Pypy und war enttäuscht, dass die Leistung mit Pypy weniger als 10% besser als mit python3 (Anaconda).
Durchschnittliche Zeit 50k Pakete mit PyPy ist 52,54 Sekunden laufen
Durchschnittliche Zeit zu laufen 50k Pakete mit python3 ist 56,93 Sekunden
Gibt es eine Möglichkeit, Dinge zu beschleunigen?
BEARBEITEN: Unten ist das Ergebnis von cProfile, wie Sie sehen können, ist der Code ein wenig langsamer, während profiliert wird, aber die ganze Zeit damit verbracht wird, Dinge zu tun, ist scapy.
66054791 function calls (61851423 primitive calls) in 85.482 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
957/1 0.017 0.000 85.483 85.483 {built-in method builtins.exec}
1 0.001 0.001 85.483 85.483 parser-3.py:1(<module>)
1 0.336 0.336 83.039 83.039 sendrecv.py:542(sniff)
50001 0.075 0.000 81.693 0.002 utils.py:817(recv)
50001 0.379 0.000 81.618 0.002 utils.py:794(read_packet)
795097/50003 3.937 0.000 80.140 0.002 base_classes.py:195(__call__)
397549/50003 6.467 0.000 79.543 0.002 packet.py:70(__init__)
397545/50000 1.475 0.000 76.451 0.002 packet.py:616(dissect)
397397/50000 0.817 0.000 74.002 0.001 packet.py:598(do_dissect_payload)
397545/200039 6.908 0.000 49.511 0.000 packet.py:580(do_dissect)
199083 0.806 0.000 32.319 0.000 dns.py:144(getfield)
104043 1.023 0.000 22.996 0.000 dns.py:127(decodeRR)
397548 0.343 0.000 15.059 0.000 packet.py:99(init_fields)
397549 6.043 0.000 14.716 0.000 packet.py:102(do_init_fields)
6673299/6311213 6.832 0.000 13.259 0.000 packet.py:215(__setattr__)
3099782/3095902 5.785 0.000 8.197 0.000 copy.py:137(deepcopy)
3746538/2335718 4.181 0.000 6.980 0.000 packet.py:199(setfieldval)
149866 1.885 0.000 6.678 0.000 packet.py:629(guess_payload_class)
738212 5.730 0.000 6.311 0.000 fields.py:675(getfield)
1756450 3.393 0.000 5.521 0.000 fields.py:78(getfield)
49775 0.200 0.000 5.401 0.000 dns.py:170(decodeRR)
1632614 2.275 0.000 4.591 0.000 packet.py:191(__getattr__)
985050/985037 1.720 0.000 4.229 0.000 {built-in method builtins.hasattr}
326681/194989 0.965 0.000 2.876 0.000 packet.py:122(add_payload)
...
EDIT 2: Vollständiges Codebeispiel:
from scapy.all import *
from scapy.utils import PcapReader
import time, sys, logging
COUNT = 0
def customAction(packet):
global COUNT
COUNT = COUNT + 1
file_temp = sys.argv[1]
path = '/'.join(file_temp.split('/')[:-2])
file_in = '/'.join(file_temp.split('/')[-2:])
name = file_temp.split('/')[-1:][0].split('.')[0]
os.chdir(path)
q_output_file = 'processed/q_' + name + '.csv'
a_output_file = 'processed/a_' + name + '.csv'
log_file = 'log/' + name + '.log'
logging.basicConfig(filename=log_file, level=logging.DEBUG)
t0=time.time()
sniff(offline=file_in, prn=customAction, lfilter=lambda x:x.haslayer(DNS), store=0)
t1=time.time()
logging.info("File '{}' took {:.2f} seconds to parse {} packets.".format(name, t1-t0, COUNT))
Nach https://gist.github.com/dpifke/2244911 sollte defaultdict nicht der Grund sein, dass pypy langsamer als python3 ist. Durch den Prozess der Beseitigung scheint es, dass der offensichtliche Schuldige scapy + pypy ist. – deltap
Können Sie ein konkretes Beispiel für PyPy geben? Wenn es wirklich langsamer ist (selbst für große Dateien), könnte das an einer fehlenden Optimierung in PyPy selbst liegen, die wir reparieren könnten. –
Nach einigen Code-Optimierungen kann ich jetzt eine 10% ige Verbesserung der Ausführungsgeschwindigkeit mit Pypy erzielen. – deltap