IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

[Tkinter][Text] Problème mémoire avec grand texte [Python 2.X]


Sujet :

Tkinter Python

  1. #1
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut [Tkinter][Text] Problème mémoire avec grand texte
    Bonjour,

    je rencontre actuellement des problèmes de mémoire qui impactent très rapidement les performances d'affichage de mon application.
    Pour faire simple c'est un widget Text avec une scrollbar qui affiche le contenu d'un fichier pouvant dépasser les 10ko de texte.
    Ce texte est parsé pour affecter des tags de couleur à certains mots. Le texte est ajouté au widget ligne par ligne et non en une seule fois.

    Au bout d'un certain nombre de ligne l'ajout se fait de plus en plus lentement.
    J'ai comme l'impression qu'il tente de redessiner tout le contenu du widget à chaque insert...
    Auriez-vous une idée pour palier à cela ?

    Dans le pire des cas je pensais à n'afficher que quelques lignes et recoder une scrollbar qui irait lire et parser le texte qui suit à la demande mais c'est assez lourd niveau code...
    Donc s'il existe une solution native pour palier à mon problème je suis tout ouïe.

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Citation Envoyé par transgohan Voir le message
    Donc s'il existe une solution native pour palier à mon problème je suis tout ouïe.
    Pour pallier... il faudrait un diagnostic et pour avoir un diagnostic, il faut pouvoir reproduire et pour cela fournir un peu de code qui le permette.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Je travaille sur un réseau coupé d'internet et duquel je n'ai pas le droit de rapatrier du code, sinon j'aurai inclus de suite ce dit code.

    Je vais cependant travailler sur un poc similaire pour tenter de vous poster du code, mais je n'ai aucune possibilité d'avoir un environnement python sur cet ordinateur...
    Donc pas facile de vous poster un code qui serait représentatif de mon problème et sans erreurs de code...
    J'ai trouvé des sites permettant d'exécuter du code python en ligne mais bloqué par le firewall de l'entreprise.
    Il ne me reste plus qu'à tenter de reproduire ce bug chez moi...

    Je continue d'investiguer et je m'oriente plutôt vers un problème de thread que du widget en tant que tel au final...

    Est-il possible d'avoir des réentrances d'une callback appelée avec la méthode after sur l'objet Tk ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def maj :
      # ...
      # traitement x
      # ...
      Mafenetre.after(1000,maj)
    J'ai dans cette callback une fifo que je dépile, j'observe qu'il dépile pendant un temps des centaines de message en même temps puis au bout d'un moment il les dépile un à un.
    Comme si le scheduler était à la traîne...

    Note : cette fifo est remplie dans un autre thread (qui n'a rien à voir avec TKinter, et que je nommerai ThreadData).
    Note2 : j'ai déjà pu rendre l'affichage plus véloce en enlevant du threadData des printf sur la console (dans le gros volume de données il y en a qui sont incorrectes et donc qui ne peuvent être parsées).

    Niveau architecture voici en gros ce que fait mon programme (mais j'admets que du code serait mieux ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ThreadInput :
       Tant qu'il reste des choses à lire Faire :
           data = Lecture source
           Empiler data => fifo_data
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ThreadData :
       Toujours Faire :
            data <= Dépiler fifo_data
            retour = Traitement(data)
            Si retour = OK Faire :
                 Empiler data => fifo_ihm
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ThreadIhm :
    fonction update
         nb = 0
        Tant que nb < 500 ET fifo_ihm n'est pas vide Faire :
            data <= Dépiler fifo_ihm
            tags = détecter_tags(data)
            insérer data à Text_Tkinter
            insérer tags à Text_Tkinter
            nb++
         IHM.after(100, update)

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Vous faites comme vous pouvez mais si vous voulez de l'aide pas facile de comprendre ce qu'il se passe sans un minimum de code. Tout au plus on peut essayer de coder l'histoire que vous racontez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    from tkinter import Button
    from tkinter.scrolledtext import ScrolledText
    text = ScrolledText()
    text.tag_config("odd", background="yellow", foreground="red")
    text.tag_config("even", foreground="blue")
    text.pack()
     
    def addlines():
        line = int(text.index('end-1c').split('.')[0])
        for x in range(1, 100000, 2):
            text.insert('end', str(line + x) + '***' + 'ab' * 20 + '\n', "odd")
            text.insert('end', str(line + x + 1) + '***' + 'cd' * 20 + '\n', "even")
     
    Button(text='more', command=addlines).pack()
    Button(text='go end', command=lambda: text.see('end')).pack()
     
    text.mainloop()
    Et effectivement, lorsque je dépasse 1 million de lignes çà commence à peiner un peu mais, si je ne me trompe pas, çà dépasse largement les 10 Ko mentionnés au départ.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Je viens de rentrer à la maison et j'ai un peu de temps donc je vais m'installer l'environnement et je vais tenter de reproduire le problème.

    10k de texte qui doivent être interprétés, cela se transforme facilement en 100k de texte en fait à la fin.
    Cependant j'ai un collègue qui avec le même logiciel et 130k en entrée n'avait pas de ralentissement (mais il avait un fichier d'entrée nécessitant peu de traitement, donc ça rejoint un peu l'idée que c'est peut être plus le traitement que le widget en lui même).

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  6. #6
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Je viens de reproduire le problème et effectivement je m'oriente vers un problème de thread plus que de widget.

    Voici le poc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    from tkinter import *
    import threading
    import sys
    import time
    import queue
     
    fin_thread_data_G = False
     
    taille_data_G = 0
    taille_lu_G = 0
    trame_G = ""
    nb_trame_G = 0
    def Traitement(octet_P) :
    	global taille_data_G
    	global taille_lu_G
    	global fifo_ihm_G
    	global trame_G
    	global nb_trame_G
     
    	if taille_data_G == 0 :
    		taille_data_G = 44 # taille de la chaine
    		trame_G = ""
    	if taille_lu_G < taille_data_G :
    		taille_lu_G = taille_lu_G + 1
    		trame_G = trame_G + chr(octet_P)
     
    	if taille_data_G > 0 and taille_data_G == taille_lu_G :
    		trame_G = trame_G + " " + str(nb_trame_G) + "\n"
     
    		array_texte = []
    		temp = trame_G.split("[texte")
    		array_texte.append({"text":temp[0], "color":"grey"})
    		tmp = temp[1].split("[/texte]")
    		c = tmp[0].split("]")
    		array_texte.append({"text":c[1], "color": c[0][1:]})
    		array_texte.append({"text":tmp[1], "color":"grey"})
     
    		nb_trame_G = nb_trame_G + 1
    		taille_data_G = 0
    		taille_lu_G = 0
    		while fifo_ihm_G.full == True :
    			time.sleep(1)
    		fifo_ihm_G.put(array_texte)
     
     
    def Thread_Data() :
    	global fifo_data_G
    	global fin_thread_data_G
     
    	with open("data.txt", "rb") as file : # 98819 éléments
    		octets = file.read()
    		for octet in octets :
    			while fifo_data_G.full == True :
    				time.sleep(1)
    			fifo_data_G.put(octet)
    	file.close()
    	print("\tfin Thread_Data")
    	fin_thread_data_G = True
    	return 0
     
     
    tag = 0
    def update() :
    	global fifo_ihm_G
    	global text
    	global ihm
    	global tag
     
    	nb = 0
     
    	while nb < 500 and fifo_ihm_G.empty() == False :
    		try :
    			texte = fifo_ihm_G.get(True, 0.0005)
    			for t in texte :
    				text.insert("end", t["text"])
    				start = "end -%dc" % len(t["text"])
    				end = "end -1c"
    				text.tag_add(tag, start, end)
    				text.tag_config(tag, foreground=t["color"])
    				tag = tag + 1
    			nb = nb + 1
    		except queue.empty :
    			print("empty %d" % nb)
    	print("fifo:%d" % nb)
    	text.see("end")
     
    	ihm.after(100, update)
     
    def Thread_IHM() :
    	global text
    	global ihm
     
    	ihm = Tk()
    	ihm.grid()
     
    	text = Text(ihm);
    	text.grid(row=0, column=0, sticky="NSEW")
    	scrollbar = Scrollbar(ihm, command=text.yview)
    	scrollbar.grid(row=0, column=1, sticky="NS")
     
    	ihm.grid_rowconfigure(0, weight=1)
    	ihm.grid_columnconfigure(0, weight=1)
    	ihm.grid_columnconfigure(1, weight=1)
     
    	ihm.after(100, update)
     
    	ihm.mainloop()
     
    def Thread_Parse() :
    	while fin_thread_data_G == False or fifo_data_G.empty() == False :
    		while fifo_data_G.empty() == True :
    			time.sleep(1)
    		octet = fifo_data_G.get(True, 0.5)
    		Traitement(octet)
    	print("\tfin Thread_Parse")
    	return 0
     
    def Main() :
    	t_ihm = threading.Thread(target=Thread_IHM)
    	t_data = threading.Thread(target=Thread_Data)
    	t_parse = threading.Thread(target=Thread_Parse)
     
    	t_ihm.start()
    	t_data.start()
    	t_parse.start()
     
    	t_ihm.join()
    	t_data.join()
    	t_parse.join()
     
    fifo_data_G = queue.Queue()
    fifo_ihm_G = queue.Queue()
    Main()
    data.txt (98819 fois cette chaîne de caractères)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ceci est un [texte=red]test[/texte] de texte
    Je suis allé à l'essentiel pour reproduire l'architecture de mon programme et reproduire les ralentissements.
    Avec l'ajout des print j'observe que le thread de l'ihm ne reprend correctement la main que lorsque les deux autres ont terminés leur travail.
    (d'ailleurs, qu'existe-t-il pour Python afin de debugguer efficacement du multithread ?)
    On peut donc en penser que fifo.put ne lance pas le scheduler...
    Je n'observe cependant pas de latence du scroll une fois que les données sont toutes affichées, mais je le fait tourner actuellement sur un bon PC alors qu'au boulot c'est une chaudière ce qui explique peut être l'écart.

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Bravo pour l'effort.
    Ceci dit, rien qu'en regardant la partie "tkinter", çà reçoit une liste de dictionnaire où l'information se résume au découpage en (texte, color). Déjà je ne comprend pas pourquoi faites une liste de dictionnaires plutôt qu'une liste de tuple voire une flat list qui pourrait être passé à text.insert en un seul appel, ni pourquoi vous créez systématiquement un nouveau tag (plutôt que de collecter ceux déjà crées et les ré-utiliser).
    Je ne vois pas non plus l'intérêt d'avoir un thread pour lire tout le fichier qui expédie caractère par caractère à un autre thread qui fait de la peinture pour à la fin récupérer ce qu'il faut afficher: vous pouvez lire le fichier par chunks (file.read accepte un size en paramètre) pour découper cela bien plus simplement et vous passer de tous ces threads.
    note: n'oubliez pas que multiplier les threads avec Python ne va pas augmenter le nombre de CPU qui vont pouvoir bosser (i.e. çà n'ira pas plus vite qu'avec un CPU à cause du GIL), çà sert juste à ne pas bloquer le programme dans l'attente de la fin d'activités qui attendent que çà arrive (une lecture réseau par exemple) sans trop être gourmandes en CPU.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Merci de ta réponse.
    Alors j'ai créé un poc pour reproduire le problème, mais du coup l'archi peut paraître bizarre cependant elle a son intérêt.

    Le thread de lecture est normalement lié à un port série, qui est en polling.
    Le thread de parsing est dû au fait que les traitements sont conséquents (dans mon poc effectivement c'est pas grand chose, mais dans mon application réelle c'est au moins 60% du CPU) et que l'ihm n'est pas là pour faire cela.
    Pas possible non plus de mettre le parsing dans le thread du port série car trop consommateur en temps et je perdrai des octets.

    Partant de ces informations là pourrais-tu me rediriger vers une doc ou un exemple de ce que tu mets en avant ? (notamment la partie liée au text : un seul tag pour tout gérer, un seul appel insert)
    J'avoue ne pas maîtriser très bien cette librairie, j'ai débuter la lecture de la doc il y a 3 jours et c'est avec ça que j'ai pondu ce premier jet.
    Je n'étais pas au courant du Scrolledtext par exemple.

    Edit : j'ai parcouru le sujet parlant du GIL, cela semble être ce qui me pose problème à première vue...
    J'ai longtemps regardé sur le net et j'ai pu voir que la gestion des threads en python... Bah ça n'existe pas... T_T
    Ou alors il faut une seule tâche qui va distribuer des tâches, mais dans mon cas cela ne va pas être possible avec Tkinter qui créé son propre thread...

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par transgohan Voir le message
    Partant de ces informations là pourrais-tu me rediriger vers une doc ou un exemple de ce que tu mets en avant ? (notamment la partie liée au text : un seul tag pour tout gérer, un seul appel insert)
    Un seul tag pour tout gérer, non il faudra autant de tags que de couleurs (s'il n'y a que des couleurs).
    Les documentations de tkinter ne rendent pas trop compte de cette possibilité, il faut lire celle de TCL/Tk. Et si j'applique çà à mon exemple précédent, à la place de ces 2 inserts:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            text.insert('end', str(line + x) + '***' + 'ab' * 20 + '\n', "odd")
            text.insert('end', str(line + x + 1) + '***' + 'cd' * 20 + '\n', "even")
    On peut écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            t1 = str(line + x) + '***' + 'ab' * 20 + '\n'
            t2 = str(line + x + 1) + '***' + 'cd' * 20 + '\n'
            args = t1, "odd", t2,  "even"
            text.insert('end', *args)
    et dans le cas de plusieurs "tags", args = t1, "odd", t2, "even" s'écrit aussi args = t1, ("odd",), t2, ("even",) i.e. la liste des tags est passée sous forme de tuple - ici à un élément -.

    Ou alors il faut une seule tâche qui va distribuer des tâches, mais dans mon cas cela ne va pas être possible avec Tkinter qui créé son propre thread...
    çà c'est ce qu'on raconte aux débutants pour qu'ils s'appliquent à apprendre la programmation évènementielle.... Avec quelque précautions, vous pouvez remplacer l'appel à mainloop et l'attente des évènements par des modifications de l'affichage (des inserts) et des appels à update.
    Un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    from tkinter import Button
    from tkinter.scrolledtext import ScrolledText
    import time
     
    text = ScrolledText()
    text.tag_config("odd", background="yellow", foreground="red")
    text.tag_config("even", foreground="blue")
    text.pack()
     
    def addlines():
        line = int(text.index('end-1c').split('.')[0])
        for x in range(1, 10000, 2):
            t1 = str(line + x) + '***' + 'ab' * 20 + '\n'
            t2 = str(line + x + 1) + '***' + 'cd' * 20 + '\n'
            args = t1, "odd" , t2, "even"
            text.insert('end', *args)
     
    for x in range(10):
        addlines()
        text.update()
        time.sleep(0.1)
    text.see('end')
    input('foo')
    note: le problème de cette méthode est que l'appel à .update va traiter tous les évènements en attente, ce qui peut déclencher des callbacks qui changeront l'état global qui demanderait à ce qu'on arrête de boucler comme un malade. Donc çà devient "compliqué" (lorsqu'on découvre l’évènementiel) mais ce n'est pas ingérable.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Merci pour l'explication sur les tags, il va falloir que je creuse ça, ça m'a l'air très intéressant.

    Concernant le remplacement de mainloop, cela ne rend-t-il pas l'interface totalement inactive ?
    Si on a par exemple des boutons sur l'interface en plus du widget Text, cette façon de faire ne les rend-t-ils pas inopérant ?

    Ou bien les callbacks sont gérées en dehors du mainloop ce qui fait que cela n'a pas d'incidence ?
    (hormis le fait qu'il faille gérer dans cette boucle de traitement les update de tous les composants)

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par transgohan Voir le message
    Concernant le remplacement de mainloop, cela ne rend-t-il pas l'interface totalement inactive ?
    Si on a par exemple des boutons sur l'interface en plus du widget Text, cette façon de faire ne les rend-t-ils pas inopérant ?
    .update traite les évènements en attente puis sort.
    .mainloop le fait en permanence jusqu'à ce qu'il rencontre "quit".

    Donc la réactivité de l'interface dépendra de l'intervalle de temps qu'il y aura entre 2 .update.
    (pour ne pas traiter les callbacks, on peut utiliser .update_idletasks).
    Le problème d'.update, c'est qu'il faut éviter de l'appeler dans un callback et que suivant la pile d'évènements à traiter, sa durée pourra être +/- longue.

    Autre point que j'ai oublié d'évoquer, si vous avez besoin de "CPU", jetez un œil au module multiprocessing. Comme vous utilisez des Queue pour échanger vos messages, çà ne devrait pas être trop compliqué à mettre en œuvre.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    C'est plutôt clair, merci du temps pris.
    Il ne me reste plus qu'à trouver du temps pour mettre tout cela en œuvre et voir l'amélioration.

    Edit :
    Bon j'ai fini par trouver un peu de temps entre deux compilations et j'ai poursuivi mon instrumentation.
    Pour finir par trouver ce qui n'allait pas pour l'affichage d'un fichier texte !

    Il semble effectivement qu'utiliser une multitude de tag lui donne de sacrées nausées à ce cher python.
    Ajouter à cela le fait que le traitement d'insertion de 500 éléments ne pouvaient se faire en 100ms et vous avez résolu le problème !

    Actuellement en traitant 20 lignes à la fois dans la callback et sans tag je suis capable d'afficher sans ralentissement anormal le fichier texte.
    Il ne me reste plus qu'à comprendre l'histoire de la réutilisation des tags et le tour sera joué je pense.

    En espérant que cela corrige aussi le problème de ralentissement/freeze après une nuit de trace depuis le port série.

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  13. #13
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    100k de données brutes récupérées en une nuit, pas de ralentissement de l'interface ce matin.
    Je suis content du résultat.

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème calendar avec nested:text
    Par osman.amine dans le forum Struts 1
    Réponses: 1
    Dernier message: 05/11/2007, 11h36
  2. Problème mémoire avec InternetOpenUrl
    Par laetus dans le forum C++Builder
    Réponses: 0
    Dernier message: 06/09/2007, 08h23
  3. [VC6]Problème mémoire avec BDE
    Par Vow dans le forum MFC
    Réponses: 5
    Dernier message: 07/10/2005, 11h44
  4. Problémes mémoire avec le bde sur des bases paradox
    Par Keke des Iles dans le forum Bases de données
    Réponses: 2
    Dernier message: 27/05/2004, 16h55
  5. Problème mémoire avec une dll par chargement dynamique
    Par widze19 dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/12/2003, 13h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo