Da Speicherzugriff relativ teuer ist, würde ich das nicht unbedingt als orthogonal ansehen. Zugegeben Python ist nicht direkt die richtige Sprache, wenn man sich ueber Cache Misses Gedanken macht, aber deshalb muss man sich auch nicht wie eine Wildsau beim Speicher auffuehren.albertus hat geschrieben:Was ist schneller das Zeilenweise auslesen einer Datei mit nachfolgenden rstrip(), oder das einlesen einer Datei in einem Rutsch mit nachfolgenden split("\n")? Denn gefragt wird hier nach der Geschwindigkeit und nicht nach der Speicher schonendsten Möglichkeit.
Optimierung
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Dann probieren wir es doch einfach mal aus:BlackJack hat geschrieben:@albertus: Kein Ahnung was schneller ist. Ich weiss aber dass Deine Methode deutlich umständlicher ausgedrückt ist als ein einfaches ``list(datei)`` oder ``datei.readlines()``. In wie weit dabei wirklich zeilenweise eingelesen wird, ist dann übrigens eine Implementierungsfrage. Ohne zu *wissen* das es *deutlich* schneller ist, sollte man das IMHO nicht so umständlich schreiben.
Code: Alles auswählen
#!/usr/bin/python
import profile
def start():
f = open("/home/albert/foo.txt", "w")
abc = "abcdefghijklmnopqrstuvwxyz"
for i1 in abc:
for i2 in abc:
for i3 in abc:
for i4 in abc:
f.write(i1+i2+i3+i4+"\n")
f.close()
def test1():
datei = open("/home/albert/foo.txt")
a = set(s.rstrip() for s in datei)
def test2():
string = open("/home/albert/foo.txt").read()
a = set(string.splitlines())
#start()
profile.run("test1()")
profile.run("test2()")
Für Test 1
913958 function calls in 7.942 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 :0(open)
456976 1.903 0.000 1.903 0.000 :0(rstrip)
1 0.001 0.001 0.001 0.001 :0(setprofile)
1 0.051 0.051 7.941 7.941 <string>:1(<module>)
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 7.942 7.942 profile:0(test1())
1 2.059 2.059 7.890 7.890 rutsch.py:18(test1)
456977 3.928 0.000 5.831 0.000 rutsch.py:20(<genexpr>)
Für Test 2
7 function calls in 0.292 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 :0(open)
1 0.004 0.004 0.004 0.004 :0(read)
1 0.001 0.001 0.001 0.001 :0(setprofile)
1 0.060 0.060 0.060 0.060 :0(splitlines)
1 0.051 0.051 0.291 0.291 <string>:1(<module>)
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.292 0.292 profile:0(test2())
1 0.176 0.176 0.240 0.240 rutsch.py:23(test2)
Ich denke die Zahlen sind Aussagefähig genug. Aber ich gebe euch allen Recht meine Methode ist sehr Speicher intensiv. Ich selber würde sie auch nur anwenden wenn zwei Bedingungen erfühlt sind:
1. Beim Start des Programms um Wartezeiten zu vermeiden
2. Wenn ich die Datei nur einmal einlesen muss
Eines möchte ich noch Anmerken: Die Liste die ich zusätzlich erzeuge hat nur für eine kurze Zeit bestand.
Mit freundlichen Grüßen
Albertus
Mit freundlichen Grüßen
Albertus
Albertus
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Dir ist klar, dass `test1` mehr Arbeit leistet als `test2`? Ohne den `rstrip`-Aufruf und damit 2 aequivalenten Funktionen kommt man auf einen vernachlaessigbaren Unterschied (mit `timeit`, da profile nicht will):
Code: Alles auswählen
In [8]: timeit.timeit(test1, number=1)
Out[8]: 0.58121109008789062
In [9]: timeit.timeit(test2, number=1)
Out[9]: 0.36374115943908691
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
cofi hat geschrieben:Dir ist klar, dass `test1` mehr Arbeit leistet als `test2`? Ohne den `rstrip`-Aufruf und damit 2 aequivalenten Funktionen kommt man auf einen vernachlaessigbaren Unterschied (mit `timeit`, da profile nicht will):
Code: Alles auswählen
In [8]: timeit.timeit(test1, number=1) Out[8]: 0.58121109008789062 In [9]: timeit.timeit(test2, number=1) Out[9]: 0.36374115943908691
Ist mir klar aber in der Praxis braucht Dein Vorschlag rstrip für jede Zeile mein Vorschlag nicht. Deshalb ist der deinige langsam der meinige nicht. Aber wie gesagt es kommt drauf an ob man beim start des Programms das set einmal erzeugen muss oder nicht. Braucht man mehrmals ein neues Set sieht die Sache anders aus.
Mit freundlichen Grüßen
Albert
Mit freundlichen Grüßen
Albertus
Albertus