Laufzeit-Frage

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
crazyprogrammer
User
Beiträge: 39
Registriert: Sonntag 27. Juli 2014, 19:06

Hallo ich hab eine Frage, die mir in einem meiner Programme aufgefallen ist.
Um zu erklären, was die Frage ist, hier ein kleiner Codeschnippsel aus dem interaktiven Modus.

Code: Alles auswählen

>>> import time
>>> def f():
	print("Anfang")
	start = time.clock()
	time.sleep(10)
	end = time.clock()
	print("Ende")
	runtime = end - start
	print(runtime)

	
>>> f()
Anfang
Ende
10.000145271606918
>>> 
Warum ist die Ausgabe der Variable "runtime" nicht 10.0, sondern 10.000145271606918?
Ich hätte jetzt die Erklärung aufgestellt, dass es die Laufzeit ist. Mein System kann ja nicht jetzt eine Funktion ausführen und genau 10 Sekunden später ist das Ergebnis sofort da und beträgt 10 Sekunden.
Das mit der Laufzeit ist nun noch so eine Sache. Ich habe einiges darüber gelesen, weiß aber nicht ob dieser "Fehler" wirklich auf Grund der Laufzeit der Funktion "f" passiert ist. Wenn nein, was heißt dann jetzt genau "Laufzeit"?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Zum einen ist ein ``sleep``-Kommando nie zu 100% exakt; das ginge nur auf einem Echtzeitbetriebssystem und auch da nur bei speziellem Code und auch nur mit begrenzter Genauigkeit.

Daneben werden ja aber auch Instruktionen für das Starten der Messung und dem Beenden der Messung ausgeführt, die Zeit kosten! Das ``sleep`` wird ja nur "dazwischen" ausgeführt, aber eben nicht *unmittelbar* nach einem "atomaren" Startsignal. D.h. das ``sleep`` an sich wird schon sehr nahe an den 10 Sekunden liegen, aber das Starten und Beenden kostet eben auch Zeit!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Und clock gibt dir ein Float zurück.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

Worauf man bei diesem Thema auch noch aufpassen muss ist was `clock()` als Ergebnis liefert. Das kann je nach Betriebssystem unterschiedlich sein ob das die real vergangene Zeit oder die von diesem Prozess verbrauchte CPU-Zeit ist. In letzterem Fall kann da auch etwas deutlich unter 10.0 heraus kommen, denn `sleep()` sollte auf einem modernen Betriebssystem keine Prozessorzeit in Anspruch nehmen.

Code: Alles auswählen

In [8]: start = time.clock(); time.sleep(10); end = time.clock()

In [9]: end - start
Out[9]: 0.009999999999999953
Diesem Ergebnis entnehme ich mal das Du Dein Programm *nicht* unter Linux laufen lassen hast. :-) Denn dort liefert `clock()` verbrauchte CPU-Zeit.
crazyprogrammer
User
Beiträge: 39
Registriert: Sonntag 27. Juli 2014, 19:06

@Hyperion: Ja, davon habe ich gehört. Ein Bekannter hat mal auf so einem System folgenden Code eingegeben:

Code: Alles auswählen

while True:
    pass
Anschließend musste er den Rechner hart ausschlten, da wirklich nichts mehr ging. Gar nichts. Er meinte, dass das Programm, das den Prozessor belegt hatte, den Prozessor nicht mehr für andere Programme freigegeben hatte, weshalb selbst ein Beenden mit Strg + C nicht mehr funktionierte.

@BlackJack: Nein, ich benutzte Windows (XP). Ist es dort anders?

Außerdem habe ich nach meinem Beitrag die Funktion "f" nochmal ausgeführt. Dabei erhielt ich ein Ergebnis von 9.9999539247924249. Da dachte ich mir schon: "Kann mein PC nicht mal bis 10 zählen???" :-)
Und noch was: Was ist das für ein Code von dir, BlackJack? Das ist doch kein Python?
BlackJack

@crazyprogrammer: Na offensichtlich ist es dort anders. Du hast doch da einen deutlich anderen Wert heraus bekommen als ich. Doch das ist Python. In eine interaktive Shell eingegeben die statt '>>>' einen anderen Prompt verwendet.
crazyprogrammer
User
Beiträge: 39
Registriert: Sonntag 27. Juli 2014, 19:06

@BlackJack: Achso. Das ist dann also nicht die IDLE, sondern einfach eine andere...?
BlackJack

@crazyprogrammer: Richtig. IPython um genau zu sein.
crazyprogrammer
User
Beiträge: 39
Registriert: Sonntag 27. Juli 2014, 19:06

@BlackJack: Cool! Kann man sich die einfach so kosten- und vertragslos runterladen? Und gibt es auch nennenswerte Unterschiede zur "normalen" Shell, also der IDLE?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ja, Ipython ist freie Software, mehr gibt es auf der Website http://ipython.org/

Und IDLE ist nicht die normale Shell. IDLE ist ein Editor der eine Shell mitbringt, sich aber auch anders verhaelt als die normale, die man mittels `python` auf der Kommandozeile aufruft.
crazyprogrammer
User
Beiträge: 39
Registriert: Sonntag 27. Juli 2014, 19:06

Stimmt...
Man kann in der "Python Command Line" (ist das auch eine Shell?) nicht weiter als eine Einrückungstiefe schreiben. Ist das normal?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Was soll denn "Python Command Line" sein? Der interaktive Interpreter, den du mittels `python` startest? Wenn ja: Nein, das ist nicht normal.

Code: Alles auswählen

%>  python
Python 2.7.8 (default, Sep  9 2014, 22:08:43) 
[GCC 4.9.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo():
...     def bar():
...         return 23
...     return bar()
... 
>>> foo()
23
Wichtig ist aber, dass nach der Klassen/Funktionsdefinition eine Leerzeile kommt:

Code: Alles auswählen

>>> def baz():
...     return 3
... baz()
  File "<stdin>", line 3
    baz()
      ^
SyntaxError: invalid syntax
crazyprogrammer
User
Beiträge: 39
Registriert: Sonntag 27. Juli 2014, 19:06

Naja, so wie es aussieht, hast du Linux. Ich arbeite mit Windows.
Und da starte ich diese Shell (von der ich glaube, dass es eine ist) über "Start | Alle Programme | Python 3.4 | Python (command line)"
Dann erscheint ein Fenster, dass sehr dem von z. B. cmd ähnelt. In diesem Fenster mit dem Titel "Python (command line)" steht diese Ausgabe und der Eingabeprompt ">>> ":

Code: Alles auswählen

Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> 
Hier ein Beispiel, bei dem ich zwei Mal die Funktion "f" definiere. Einmal mit und einmal ohne Exeption.

Code: Alles auswählen

Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> def f():
... print("etwas")
  File "<stdin>", line 2
    print("etwas")
        ^
IndentationError: expected an indent block
>>> def f():
...     print("etwas")
...     print("noch etwas")
... 
>>> f()
etwas
noch etwas
>>> 
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ich verstehe jetzt nicht, was dein Problem ist.

`f1` ist kein gültiges Python, weil die Zeile nicht eingerückt ist. Darum auch die Exception, die dir genau das sagt.
Und weil die Einrückung bei `f2` stimmt bekommst du eben keine Exception.
crazyprogrammer
User
Beiträge: 39
Registriert: Sonntag 27. Juli 2014, 19:06

Schon, das habe ich dann beim Tippen des Beispiels auch kapiert. Aber vorher habe ich mich immer gewundert, warum ein Error erzeugt wird, wenn ich eine Funktion definiere.
In der Entwicklungsumgebung IDLE, mit der eigentlich immer arbeite, wird automatisch eingerückt. In dieser Shell aber nicht. Da muss man noch alles selber machen. :-D
Antworten