Python Programm braucht "Anlaufszeit"

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
benjamin222
User
Beiträge: 6
Registriert: Donnerstag 15. Juli 2021, 16:01

Code: Alles auswählen

import easyocr
from time import time
import os


print(time())

reader=easyocr.Reader(['en'])

print(time())

path='D:/Bilder/debugoutput/testauswahl4/'

start=time()

for bild in os.listdir(path):
    result=reader.readtext(path+bild)

    print(time())



end=time()
print(end-start)
Wenn ich das ausführe, liegen zwischen den ersten ausgegebenen Zeiten 4 Sekunden. Danach rattert das Programm dann recht schnell durch den Rest durch. Woran liegt das genau?
Und kann man das irgendwie beschleunigen?
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Pfade stückelt man nicht mit + zusammen. Pfade sind keine einfachen Strings. Benutze pathlib.Path.

Code: Alles auswählen

import easyocr
from pathlib import Path

reader = easyocr.Reader(['en'])
path = Path('D:/Bilder/debugoutput/testauswahl4/')
for bild in path.iterdir():
    result = reader.readtext(str(bild))
easyocr lädt weitere Bibliotheken nach. Das braucht halt Zeit. Die 58s bis Dein PC hochgefahren ist, stören Dich ja auch nicht.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du wirst das nicht beschleunigen können. Was du erreichen kannst ist, diese Kosten nicht andauernd zu bezahlen. Indem dein Programm dauerhaft läuft, und Arbeitsaufträge per Schnittstelle entgegennimmt.
benjamin222
User
Beiträge: 6
Registriert: Donnerstag 15. Juli 2021, 16:01

@ __deets__

D.h., dass ich dann einfach

Code: Alles auswählen

reader = easyocr.Reader(['en'])
nicht in die Funktion packe, die das benutzt, sondern einfach so direkt ob in meine Python-Datei!?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein, weil das eine globale Variable wäre. Aber als Argument oder Attribut einer Klasse, ja. Und natürlich eben auch nur einmal instantiiert.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

ich glaube __deets__ meinte etwas in dieser Art:

Code: Alles auswählen

#!/usr/bin/env python3

import easyocr
from time import monotonic
from pathlib import Path

TESTSELECTION = Path('D:/Bilder/debugoutput/testauswahl4/')


def read_text(reader):
    start_time = monotonic()
    for bild in TESTSELECTION.iterdir():
        result = reader.readtext(bild)
    end_time = monotonic()
    print(start_time - end_time)


def main():
    reader = easyocr.Reader(['en'])
    read_text(reader)


if __name__ == '__main__':
    main()

Jetzt ändert sich zwar erst mal nicht viel, doch der Aufbau ist jetzt etwas geschickter. 'easyocr' wird nur einmal geladen. Dann kannst du 'read_text' so oft du willst aufrufen, und es wird ohne die Ladezeit von 'easycor' ausgeführt. Natürlich musst du da noch eine Schleife und Bedingungen einbauen, die deinen Anforderungen entsprechen, so dass du letztendlich dein Programm nur einmal starten musst.

Übrigends bietet sich zum messen von Zeiten 'monotonic' besser an, als 'time'. Vergleiche hierzu:
https://docs.python.org/3/library/time. ... .monotonic
mit
https://docs.python.org/3/library/time.html#time.time

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wobei ein bereits geladenes Modul bei einem weiteren Import innerhalb der gleichen Python-Session wiederverwendet wird. Da ist es also egal, wo man den Import platziert. Dass die Imports ganz am Anfang erfolgen sollten, dient vor allem Lesbarkeit, weniger der Performance. Begründete Ausnahmefälle wie "Lazy Loading" mal ausgenommen.

Hier sollte wirklich der Fokus auf der Schnittstelle liegen. Denkbar neben vielen anderen Möglichkeiten wäre z.B. ein Microservice, der dauerhaft läuft und Befehle via JSON annimmt. Das ist quasi ein eigener (Software-)Server, der auch auf dem gleichen Rechner sein kann. Falls das nicht sofort einleuchtend ist, einfach mal mit der eigentlichen Bedeutung eines Servers beschäftigen. Ein gängiges Framework dafür ist übrigens Flask. Wenn du die JSON-Schnittstelle fertig hast, dann ist der Einbau der Flask-Schicht relativ trivial.

EDIT: JSON ist natürlich zum Anstoßen des Readers gemeint. Die Textausgabe würde ich als Datei ausliefern.
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@snafu: Wenn Du schon einen Webserver als Lösung vorschlägst, warum dann nicht auch die Ergebnisse per REST zurückgeben? Wozu die Datei?
Antworten