Pb memory | |
Philippe | 29-May-2018/8:27:37 |
Bonjour à tous, Je me suis éloigné du Rebol depuis quelques années, mais je regarde encore de temps en temps ce qu'il se passe sur le forum et bien sûr sur Red. Pour les besoins d'un projet, j'ai déterré un bout de code que j'avais fait il y a fort fort longtemps et qui permet d'extraire d'un log (ici Apache) les temps de requêtes et de créer un graphe par minute du nombre de hits et en fonction du temps de la requête le hit est sous forme d'une box plus ou moins colorée. Je me heurte à un souci de mémoire de Rebol dès que je veux agrandir la taille de la box ou d'un nombre important de hits . Si quelqu'un a une idée d'optimisation, je suis preneur, car je suis un peu (beaucoup) rouillé !! Les données (anonymisées) se présentent comme cela (l'avant-avant-dernier chiffre est le temps de la requête en microsecondes ) : [24/05/2018:00:43:01]|TEST|TEST|TEST|TEST|TEST|TEST|245880|0|200 [24/05/2018:00:43:00]|TEST|TEST|TEST|TEST|TEST|TEST|1463436|0|200 [24/05/2018:00:43:01]|TEST|TEST|TEST|TEST|TEST|TEST|2208594|2|200 [24/05/2018:00:43:02]|TEST|TEST|TEST|TEST|TEST|TEST|1572024|0|200 et le code : rebol [] change-dir %/tmp/stats ; limits = [L1 L2 L3 L4] bornes qualité temps de réponse 1s 2s 5s 10s limits: [1000000 2000000 5000000 10000000] sizeu: 1x10 pixel-size: 35x10 ; taille d'un rectangle de couleur pixel-dir: 1x0 ; pour mettre les rectangles cote à cote get-tuple!: func [val limX limY /local var ][to-integer ((255 * ((to-integer val) - limX)) / (limY - limX))] ; end func time-to-color!: func [ value /local var ][ value: to-integer value if (lesser-or-equal? value limits/1) [var: 0.255.0] ; < L1 green, all seems good if all [(greater? value limits/1) (lesser-or-equal? value limits/2)] [ var: to-tuple reduce [(get-tuple! value limits/1 limits/2) 255 0] ] ; beetween L1, and L2, 0.255.0 -> 255.255.0 vert au jaune if all [(greater? value limits/2) (lesser-or-equal? value limits/3)] [ var: to-tuple reduce [255 (get-tuple! value limits/3 limits/2) 0] ] ; beetween L2, and L3, 255.255.0 -> 255.0.0 jaune au rouge if all [(greater? value limits/3) (lesser-or-equal? value limits/4)] [ var: to-tuple reduce [(get-tuple! value limits/4 limits/3) 0 0] ] ; beetween L3, and L4, 255.0.0 -> 0.0.0 rouge au noir if (greater? value limits/4) [ var: 0.0.0 ] ; > L4, black, careful return var ] ; end func ; ------ MAIN / INIT --------------------------- ; on crée un tableau de minutes [ 00:00 00:01 00:02 ... 23:59 ] tableau-minutes: copy [] for v 00:00 23:59 00:01 [ append tableau-minutes either (lesser? v 10:00) [rejoin ["0" v] ][form v] append/only tableau-minutes copy [] ] ;==tableau-minutes: ["00:00" [] "00:01" [] "00:02" [] ... "23:59" [] ] ; -----reading input files ---- datas: read/lines request-file/only ; ------ MAIN / PARSING ZONE --------------------------- foreach line datas [ tabinfos: parse line {[]"| } ; tabinfos/4 = date | tabinfos/12 = temps_requete timer: (val: parse tabinfos/2 {:} rejoin [val/2 ":" val/3]) ; timer= heure dans la ligne de log ; probe tabinfos/12 if find tableau-minutes :timer [repend tableau-minutes/:timer (time-to-color! tabinfos/12 )] ; tabinfos/9)] ] ; end foreach tableau-data: copy tableau-minutes ; -------- MAIN / Building Image ---------------------------- out: [ origin 0 backeffect [gradient 0x1 white white] ; silver across space 1x1 ] ; --- basic face for reduce memory ----------- simple-image: make object! [ type: 'face ; mandatory offset: 0x0 ; mandatory size: pixel-size ; mandatory span: none ; mandatory pane: none ; mandatory text: "basic image" ; mandatory (sinon erreur titre) color: 255.255.255 ;(black by default if no color attribute) feel: make object! [ ] ; erreur si feel absent ] ; ------ prepapre statement --- foreach [label-hour tab-colors] tableau-data [ ;blk-img: clear [] img: make image! pixel-size * as-pair length? tab-colors 1 ; position où on dessine dans l'image pos: 0x0 if (not empty? tab-colors) [ ; pour chaque couleur foreach colr tab-colors [ ; append blk-img compose/deep [image (make image! compose/deep [(sizeu) (colr) ])] img: draw img compose [pen (colr) fill-pen (colr) box (pos) (pos + pixel-size)] ; position du rectangle suivant pos: pos + pixel-size * pixel-dir ] ; end foreach ] append out compose/deep [ ;text (label-hour) ;pad 10x0 ;(blk-img) text (to-string label-hour) 40 image (img) return ] ] ;write clipboard:// mold out code: compose/deep [layout [(out)] ] code: do code ;view/new center-face code ;unview/only code ; ---- PB de memoire --------- recycle res-img: to-image code composite-file: %/tmp/stats/test-analyse-apacheX.png save/png composite-file res-img print rejoin [ "End ... : "] halt Merci de votre aide ===Philippe | |
Darkblue | 30-May-2018/14:13:42 |
Bonjour Philippe, tu pourrais dans un 1er temps ne pas faire tableau-data: copy tableau-minutes mais utiliser tableau-minutes simplement Tu peux aussi ne pas faire de read/lines du fichier s'il est volumineux m'ai d'ouvrir un port en lecture ligne par ligne avec open/read/lines/direct Olivier | |
DideC | 2-Jul-2018/7:22:42 |
Il y a surement pas mal d'autres optimisations. Mais je pense que ça : code: compose/deep [layout [(out)] ] code: do code ...est tout simplement équivalent à : [ocde]code: layout out[/code] | |
DideC | 2-Jul-2018/7:41:31 |
Tu peux aussi pas mal optimiser le code du départ et attention au nommage des fonctions (to-tuple! ne renvoyant pas un tuple! ??!!)get-color-amount: func [val limX limY /local var ][to integer! (to integer! val) - limX * 255 / (limY - limX)] time-to-color: func [value /local var] [ value: to integer! value return case [ ; < L1 green, all seems good value <= limits/1 [0.255.0] ; beetween L1, and L2, 0.255.0 -> 255.255.0 vert au jaune value <= limits/2 [to tuple! reduce [get-color-amount value limits/1 limits/2 255 0]] ; beetween L2, and L3, 255.255.0 -> 255.0.0 jaune au rouge value <= limits/3 [to tuple! reduce [255 get-color-amount value limits/3 limits/2 0]] ; beetween L3, and L4, 255.0.0 -> 0.0.0 rouge au noir value <= limits/4 [to tuple! reduce [get-color-amount value limits/4 limits/3 0 0]] ; > L4, black, careful true [0.0.0] ] ] | |
DideC | 2-Jul-2018/8:24:32 |
Et puis dans ton tableau-minute, tu peux surtout stocker tes étiquettes sous forme de time! plutôt que de string!, cela prendra moins de mémoire et accélérera les recherches. Tu fais déjà la conversion en string pour l'affichage. De manière générale, il y a bien trop de 'reduce et 'compose inutiles qui te consomme pas mal de mémoire. Voilà ma version plus épurée mais gardant la même logique : Rebol [] limits: [1000000 2000000 5000000 10000000] sizeu: 1x10 pixel-size: 35x10 ; taille d'un rectangle de couleur pixel-dir: 1x0 ; pour mettre les rectangles cote à cote get-color-amount: func [val limX limY /local var ][to integer! (to integer! val) - limX * 255 / (limY - limX)] time-to-color: func [value /local var] [ value: to integer! value return case [ ; < L1 green, all seems good value <= limits/1 [0.255.0] ; beetween L1, and L2, 0.255.0 -> 255.255.0 vert au jaune value <= limits/2 [to tuple! reduce [get-color-amount value limits/1 limits/2 255 0]] ; beetween L2, and L3, 255.255.0 -> 255.0.0 jaune au rouge value <= limits/3 [to tuple! reduce [255 get-color-amount value limits/3 limits/2 0]] ; beetween L3, and L4, 255.0.0 -> 0.0.0 rouge au noir value <= limits/4 [to tuple! reduce [get-color-amount value limits/4 limits/3 0 0]] ; > L4, black, careful true [0.0.0] ] ] tableau-minutes: [] ; 'copy inutile ici for v 00:00 23:59 00:01 [ append tableau-minutes reduce [v copy []] ] ; -----reading input files ---- ;datas: read/lines request-file/only ; pour les test de ceux qui n'ont pas ton logs ;-) datas: [ {[24/05/2018:00:40:01]|TEST|TEST|TEST|TEST|TEST|TEST|245880|0|200} {[24/05/2018:00:40:00]|TEST|TEST|TEST|TEST|TEST|TEST|1463436|0|200} {[24/05/2018:00:43:01]|TEST|TEST|TEST|TEST|TEST|TEST|2208594|2|200} {[24/05/2018:00:43:02]|TEST|TEST|TEST|TEST|TEST|TEST|1572024|0|200} {[24/05/2018:01:43:01]|TEST|TEST|TEST|TEST|TEST|TEST|245880|0|200} {[24/05/2018:03:23:00]|TEST|TEST|TEST|TEST|TEST|TEST|1463436|0|200} {[24/05/2018:04:13:01]|TEST|TEST|TEST|TEST|TEST|TEST|2208594|2|200} {[24/05/2018:04:14:02]|TEST|TEST|TEST|TEST|TEST|TEST|1572024|0|200} ] ; ------ MAIN / PARSING ZONE --------------------------- foreach line datas [ tabinfos: parse line {[]"| } ; tabinfos/4 = date | tabinfos/12 = temps_requete timer: to time! find/tail tabinfos/2 {:} ; on ne garde que ce qui est après le 1er ":" = l'heure timer/second: 0 ; on ne veut que heure:minute:0 append select tableau-minutes timer time-to-color tabinfos/12 ; tu as souvent des 'reduce ou 'compose inutiles = prend de la mémoire pour rien ] ; -------- MAIN / Building Image ---------------------------- out: [ origin 0 backeffect [gradient 0x1 white white] ; silver across space 1x1 ] ; --- basic face for reduce memory ----------- comment { ; PAS UTILISE ?! simple-image: make object! [ type: 'face ; mandatory offset: 0x0 ; mandatory size: pixel-size ; mandatory color: 255.255.255 ;(black by default if no color attribute) span: pane: feel: text: none ; mandatory ] } ; ------ prepapre statement --- foreach [label-hour tab-colors] tableau-minutes [ img: make image! pixel-size * as-pair length? tab-colors 1 pos: 0x0 foreach colr tab-colors [ img: draw img compose [pen (colr) fill-pen (colr) box (pos) (pos + pixel-size)] pos: pos + pixel-size * pixel-dir ] ; end foreach append out compose/deep [ text (to-string label-hour) 40 (either label-hour/minute = 0 ['bold]['black]) ; J'AI AJOUTE CA pour avoir un repère visuel sur les heures image (img) return ] ] code: layout out ; ---- PB de memoire --------- ;recycle composite-file: %/C/Users/Didier.2CBI/Desktop/test-analyse-apacheX.png save/png composite-file to image! code print rejoin [ "End ... : "] halt | |
Login required to Post. |