Hallo zusammen,
ich habe ein Berechnungs-Programm geschrieben, daß ziemlich lange läuft,
so 1 bis 3 Tage bis es fertig ist. Prinzipiell läuft alles es in einer while Schleife
bis das Ergebnis gefunden wird. (was aber jetzt keine Rolle spielt)
Nun will ich, ohne das Hauptprogramm in der Schleife zu beeinflussen, jede
bestimmte Zeiteinheit, z.B. jede Stunde, eine Anzeige über den Fortschritt,
also z.B. eine einfache Anzeige einer Variable des Programms erhalten.
Wie kann man dieses Problem lösen.
Bin dankbar für jeden Vorschlag.
Gruß
Digitalhans
Anfängerfrage - Zeitproblem
-
- User
- Beiträge: 168
- Registriert: Montag 9. Mai 2016, 09:14
- Wohnort: Berlin
Quellcode wäre gut.
Ansonsten gibt es die Module time oder datetime. Damit kannst du die Systemzeit abfragen und dir was daraus basteln.
Wie ermittelst du in deinem Programm Fortschritt?
Vielleicht kannst du diesen einfach immer wieder in eine Datei schreiben?
Wenn aber eine einzelne Berechnung wirklich 24h - 72h brauch, kann man natürlich nichts wegschreiben.
Ansonsten gibt es die Module time oder datetime. Damit kannst du die Systemzeit abfragen und dir was daraus basteln.
Wie ermittelst du in deinem Programm Fortschritt?
Vielleicht kannst du diesen einfach immer wieder in eine Datei schreiben?
Wenn aber eine einzelne Berechnung wirklich 24h - 72h brauch, kann man natürlich nichts wegschreiben.
-
- User
- Beiträge: 8
- Registriert: Donnerstag 12. Oktober 2017, 09:06
Danke für die schnelle Antwort.
Sourcecode ist nur eine einfache while-schleife und darin einige Berechnungen und random Generierungen
mit if Abfragen, mehr nicht. Mein Problem ist, ich will die Zeitfunktionen nicht in der whileschleife, die
milliardenfach läuf und da das Programm ja sowieso schon so lange braucht und jeder zusätzliche Code darin
das Ganze noch weiter verlängert. Es müsste also so etwas geben wie einen timer setzen und dieser soll
dann unabhängig von der Schleife nach x Sekunden einen Variablenwert ausgeben.
Ist so etwas möglich?
Gruß
Digitalhans
Sourcecode ist nur eine einfache while-schleife und darin einige Berechnungen und random Generierungen
mit if Abfragen, mehr nicht. Mein Problem ist, ich will die Zeitfunktionen nicht in der whileschleife, die
milliardenfach läuf und da das Programm ja sowieso schon so lange braucht und jeder zusätzliche Code darin
das Ganze noch weiter verlängert. Es müsste also so etwas geben wie einen timer setzen und dieser soll
dann unabhängig von der Schleife nach x Sekunden einen Variablenwert ausgeben.
Ist so etwas möglich?
Gruß
Digitalhans
Ja, aber nicht so, wie von dir gewuenscht. Man kann zwar Threads fuer so etwas nehmen, aber da Python's GIL eh erzwingt, dass diese sich serialisieren wirst du trotzdem deinen Wunsch nach ungestoerter Weiterverarbeitung fahren lassen muessen.
Und da Threads auch obendrein ein komplexes und fehlertraechiges Thema sind, wuerde ich das nicht machen.
Der Ansatz in deiner while-Schleife periodisch zu pruefen ist schon der richtige. Ich wuerde dir empfehlen statt einfach anzunehmen, dass das die Gesamtrechenzeit ungebuehrlich verlaengert, das wirklich auszuprobieren. Entweder machst du den check wirklich effektiv, oder du refaktorierst zB nach diesem Muster:
Und da Threads auch obendrein ein komplexes und fehlertraechiges Thema sind, wuerde ich das nicht machen.
Der Ansatz in deiner while-Schleife periodisch zu pruefen ist schon der richtige. Ich wuerde dir empfehlen statt einfach anzunehmen, dass das die Gesamtrechenzeit ungebuehrlich verlaengert, das wirklich auszuprobieren. Entweder machst du den check wirklich effektiv, oder du refaktorierst zB nach diesem Muster:
Code: Alles auswählen
while True: # "alte" schleife
if should_log():
log()
for _ in range(1000000):
work() # ungestoert fuer lange zeit, der range-iterator und das for sind ziemlich billig
-
- User
- Beiträge: 8
- Registriert: Donnerstag 12. Oktober 2017, 09:06
OK Danke sehr,
dann werde ich mich um eine Lösung innerhalb der Schleife bemühen.
Welche möglichst einfache und wenig rechenintensive Timerfunktion wäre denn zu empfehlen?
Mir fehlt leider mangels Wissen und Erfahrung leider noch der Überblick was am Besten dafür wäre.
Danke jetzt schon für die super Hilfe bisher
Gruß
Digitalhans
dann werde ich mich um eine Lösung innerhalb der Schleife bemühen.
Welche möglichst einfache und wenig rechenintensive Timerfunktion wäre denn zu empfehlen?
Mir fehlt leider mangels Wissen und Erfahrung leider noch der Überblick was am Besten dafür wäre.
Danke jetzt schon für die super Hilfe bisher
Gruß
Digitalhans
Ein simples "time.monotonic()" reicht, dazu ein Vergleich mit einem Zeitstempel in der Zukunft:
Code: Alles auswählen
next_logtime = time.monotonic() + LOGPERIOD
while True:
if time.monotonic() > next_logtime:
...
next_logtime = time.monotonic() + LOGPERIOD
-
- User
- Beiträge: 8
- Registriert: Donnerstag 12. Oktober 2017, 09:06
Super Danke
werde ich nachher gleich versuchen
Gruß
Digitalhans
werde ich nachher gleich versuchen
Gruß
Digitalhans
-
- User
- Beiträge: 8
- Registriert: Donnerstag 12. Oktober 2017, 09:06
Bei der Rechenzeit denke ich wird man nicht so viel rausholen können,
aber wie erwähnt bin ich ja noch Anfänger in Python.
Ich simuliere quasi einen Affen der auf eine Tastatur tippt und lasse den
solange tippen bis er ein bestimmtes Wort getippt hat. Das ist alles. Dabei
zähle ich die Versuche und die Zeit. Dabei untersuche ich z.B. die Unterschiede
zwischen z.B. "Johann" und "johann" und wie die "Arbeitszeit" des Affen mit der
Länge des Wortes steigt.
Zur Rechenzeit: Aktuell braucht mein Affe 1,193 e-06 Anschlägen pro Sekunde,
macht also also knapp 1 Mio Anschläge/Sek., recht flott denke ich. (inklusive der Abfragen des Wortes )
Zurück zu meiner Anfrage. Ich möchte jetzt, dass ich jede Stunde einen
Zwischenstand sehe, um auch zu wissen dass noch alles läuft, aber generell
ist dies genau so notwendig wie das gesamte Programm selbst
Bitte auch keine Fragen warum ich dies mache
Gruß
Digitalhans
aber wie erwähnt bin ich ja noch Anfänger in Python.
Ich simuliere quasi einen Affen der auf eine Tastatur tippt und lasse den
solange tippen bis er ein bestimmtes Wort getippt hat. Das ist alles. Dabei
zähle ich die Versuche und die Zeit. Dabei untersuche ich z.B. die Unterschiede
zwischen z.B. "Johann" und "johann" und wie die "Arbeitszeit" des Affen mit der
Länge des Wortes steigt.
Zur Rechenzeit: Aktuell braucht mein Affe 1,193 e-06 Anschlägen pro Sekunde,
macht also also knapp 1 Mio Anschläge/Sek., recht flott denke ich. (inklusive der Abfragen des Wortes )
Zurück zu meiner Anfrage. Ich möchte jetzt, dass ich jede Stunde einen
Zwischenstand sehe, um auch zu wissen dass noch alles läuft, aber generell
ist dies genau so notwendig wie das gesamte Programm selbst
Bitte auch keine Fragen warum ich dies mache
Gruß
Digitalhans
@digitalhans: auch wenn sich das Problem einfach anhört, kann man es doch auf verschiedene Art und Weise lösen, meine primitive Pythonlösung findet "johan" z.B nach 15127861 Zeichen und 9.3s macht 1.6Mio Zeichen pro Sekunde. Meine zweite Lösungsidee hat dann zufällig 14548546 Zeichen gebraucht bei 5.7s macht 2.5Mio Zeichen pro Sekunde, also deutlich schneller. Schreibt ich das ganze mit numpy, sind es z.B. 15178129 Zeichen nach 0.253s was 60Mio Zeichen pro Sekunde sind.
Du siehst also, je nach Implementierung sind es mal 3 Tage mal 2 Stunden für die selbe Rechnung.
Du siehst also, je nach Implementierung sind es mal 3 Tage mal 2 Stunden für die selbe Rechnung.
-
- User
- Beiträge: 8
- Registriert: Donnerstag 12. Oktober 2017, 09:06
hmhmh, bei mir braucht es schon sehr viel mehr Versuche bis "johan" getippt wird.
Meistens ca. 120 Millionen Mal.
Meine "Grundgesamtheit" entnehme ich aus random.choice(string.ascii_letters).
Das mit numpy hört sich ja gewaltig an. Da werde ich aber noch viel Lernen müssen denke ich.
Werde mich schon mal reinlesen/üben.
Danke für diese hilfreiche Information.
Grüße
Digitalhans
Meistens ca. 120 Millionen Mal.
Meine "Grundgesamtheit" entnehme ich aus random.choice(string.ascii_letters).
Das mit numpy hört sich ja gewaltig an. Da werde ich aber noch viel Lernen müssen denke ich.
Werde mich schon mal reinlesen/üben.
Danke für diese hilfreiche Information.
Grüße
Digitalhans
So könnte das mit numpy aussehen:
Code: Alles auswählen
def count_characters(wort):
zeichen = numpy.array(string.ascii_lowercase, dtype='c')
start = 0
old = numpy.random.choice(zeichen, len(wort))
while True:
buchstaben = numpy.random.choice(zeichen, 99999)
buchstaben[:len(wort)] = old
idx = buchstaben.tobytes().find(wort)
if idx >= 0:
return start + idx + len(wort)
start += len(buchstaben) - len(wort)
old = buchstaben[-len(wort):]
-
- User
- Beiträge: 8
- Registriert: Donnerstag 12. Oktober 2017, 09:06
@Sirius3
Vielen Dank für Dein Beispiel.
Ich werde alles durcharbeiten bis ich alles verstanden habe.
@snafu
Man darf von sich nicht immer auf andere schließen
Meine Intensionen Python zu lernen und speziell dieses
Programm sind andere, wie auch schon beschrieben.
Grüße
Digitalhans
Vielen Dank für Dein Beispiel.
Ich werde alles durcharbeiten bis ich alles verstanden habe.
@snafu
Man darf von sich nicht immer auf andere schließen
Meine Intensionen Python zu lernen und speziell dieses
Programm sind andere, wie auch schon beschrieben.
Grüße
Digitalhans
-
- User
- Beiträge: 8
- Registriert: Donnerstag 12. Oktober 2017, 09:06
@Sirius3
Habe Deinen Code in meinen eingebaut und nach dem ich mein Problem mit dem Fehler
"a-bytes-like-object-is-required-not-str" gefunden hatte ist das Ergebnis echt der Hammer.
Das Programm rechnet nun ca. 100 !!! Mal schneller als mein altes.
Ich habe schon gesehen, Python gefällt mir immer mehr und mehr
Danke nochmal für die Hilfe und beste Grüße
Digitalhans
Habe Deinen Code in meinen eingebaut und nach dem ich mein Problem mit dem Fehler
"a-bytes-like-object-is-required-not-str" gefunden hatte ist das Ergebnis echt der Hammer.
Das Programm rechnet nun ca. 100 !!! Mal schneller als mein altes.
Ich habe schon gesehen, Python gefällt mir immer mehr und mehr
Danke nochmal für die Hilfe und beste Grüße
Digitalhans
- miracle173
- User
- Beiträge: 127
- Registriert: Samstag 6. Februar 2016, 00:28
@digitalhans Wenn du glaubst das das ein Aufruf einer Zeitfunktion zu lange dauert, dann zähle einfach die Schleifenaufrufe mit, das kostet fast nichts. Und bei jedem 1000-sten Schleifenaufrufe misst du die Zeit. Damit reduzierst du die Anzahl der Aufrufe einer Zeitfunktion auf ein Promille.
Oder, nachdem dein Programm etwa 1e6 Schleifendurchläufe pro Sekunde macht, gib einfach nach allen 3.6e9 Schleifendurchläufen den Status aus.
Oder, nachdem dein Programm etwa 1e6 Schleifendurchläufe pro Sekunde macht, gib einfach nach allen 3.6e9 Schleifendurchläufen den Status aus.
mfg miracle173
https://github.com/python-forum-de/Jump-N-Run-pydesw
https://github.com/python-forum-de/Jump-N-Run-pydesw