Tja, in ist für allgemeine iteratoren, wäre natürlich möglich daß das dann auch etwas überdimensioniert für Strings ist. Da wäre dann vielleicht find angebracht, besonders wenn man nicht nur nach einem Buchstaben sondern nach einer Zeichenkette sucht.BlackJack hat geschrieben:@Alfons Mittelmeyer: Wobei: Wenn man mit dem Argument kommt, könnte man auch so ganz allgemein auf die Riesenkanone verweisen, die der C-Quelltext von CPython darstellt. Und das alles nur um Zeilen nach ein paar Buchstaben zu filtern. Das geht in Assembler mit deutlich weniger Code und Speicher, und schneller laufen wird das wohl auch.
Suche nach bestimmten Buchstaben in einer Textdatei
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Ja einen Buchstaben aus dem String jeweils mit drei Buchstaben vergleichen oder dreimal einen Buchstaben aus dem String mit je einem anderen vergleichen macht in einem Fall 4 und im anderen Fall 6 Vergleiche. Hinzu kommt aber jeweils eine Abfrage auf das String Ende und der Loop. Naja doppelt so langsam wird es schon sein als wie man das tun könnte, das ist aber auf Maschinenebene noch immer verteufelt schnell.snafu hat geschrieben:Ja, genau. Im Worst Case dreimal hintereinander den selben Text zu durchlaufen ist unglaublich performant...
Man merkt immer wieder dass du ein Troll bist.
Performanceverlust könnte natürlich durch die zwei or entstehen. Aber die zwei or sind sicherlich wesentlich performanter als jeweils für jeden Buchstaben aus dem String gleich eine Python Filter Funktion aufzurufen.
Aber anscheinend merkst Du nicht, daß Du der Troll bist.
@Alfons Mittelmeyer: Es reicht das andere merken das Du der Troll bist. Du brauchst das nicht merken, Du weisst es ja. 

Mal eine Info an den großen Python-Experten: filter(testfunc, infile) schmeißt die Zeilen raus, für die testfunc() einen leeren Container, None oder ähnliches liefert. Wir reden hier also von einem Aufruf pro Zeile, nicht pro Zeichen. Sonst würde writelines() ja auch gar nicht funktionieren. Aber schön, dass du mir deine fehlenden Fachkenntnisse ankreidest...Alfons Mittelmeyer hat geschrieben:Aber die zwei or sind sicherlich wesentlich performanter als jeweils für jeden Buchstaben aus dem String gleich eine Python Filter Funktion aufzurufen.
Wobei die Zeilen auch irgendwo her kommen müssen. Aber das ist für die Problemlösung irrelevant. Die Performancefrage wurde gar nicht gestellt.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Die Zeit um im Speicher nach Zeichen zu suchen dürfte, im Vergleich zum Datei öffnen und einlesen wohl irrerelevant sein.bwbg hat geschrieben:Wobei die Zeilen auch irgendwo her kommen müssen. Aber das ist für die Problemlösung irrelevant. Die Performancefrage wurde gar nicht gestellt.
Wenn wir allerdings nach der Performace für bereits im Speicher befindliche Zeilen fragen, ist sicher für einen Buchstaben das die performanteste Lösung:
if line.find("G" ):
Hier werden Strings übergeben und eine Umwandlung der Strings in etwas anderes erübrigt sich. Es kann gleich mit dem Suchen begonnen werden, und zwar zuerst nach dem ersten Zeichen des übergebenen Parameters, wären weitere da, würden dann auch die nächsten Zeichen verglichen. Das aber erübrigt sich und fertig.
Die am wenigstens performante Lösung, wenn wir einmal regex nicht berücksichtigen, wäre bei einem Zeichen:
Code: Alles auswählen
if set("G").intersection(line):
Schwer abschätzbar ist die Performance von:
Code: Alles auswählen
if 'G' in line:
Bei drei Zeichen allerdings ist die Frage, wieviel Zeit kosten drei Funktionsaufrufe mit konstanten, bzw. referenzierten Parametern in Python im Vergleich zum einmaligen Funktionsaufruf mit:
if set("FGM").intersection(line):
Da bin ich überfragt. Ab einer gewissen Anzahl zu suchender Zeichen ist set.intersection sowohl schneller als dreimaliges find wie auch angebracht.
Bei drei Zeichen sieht das noch gut aus und ist sicher für einen Programmieranfänger leicht verständlich:
if 'F' in line or 'G' in line or 'M' in line:
Wie das jetzt mit der Performance sein wird, schwer zu sagen, aber in diesem Fall wie gesagt, gemessen am Datei öffnen und einlesen und wohl auch wieder schreiben, wohl irrelevant.
@Alfons Mittelmeyer: beim Programmieren interessiert erstmal die Performance überhaupt nicht, sondern nur die Verständlichkeit. Um zu Prüfen ob ein String *in* einem anderen vorkommt, ist der in-Operator das offensichtlichste (und nebenbei bemerkt auch noch das performanteste). Auf Sets wird niemand als erstes kommen.
@Alfons Mittelmeyer: Das bei der `intersection()`-Lösung `line` in ein `set` umgewandelt wird ist nicht erforderlich und wird in CPython AFAIK auch nicht gemacht.
Der ``in``-Operator ist IMHO leicht abschätzbar weil der in CPython bei `str` überladen ist, also ähnlich performat sein sollte wie `find()`, bei dem aber neben dem Suchen noch der Methodenaufruf dazu kommt.
Der ``in``-Operator ist IMHO leicht abschätzbar weil der in CPython bei `str` überladen ist, also ähnlich performat sein sollte wie `find()`, bei dem aber neben dem Suchen noch der Methodenaufruf dazu kommt.