![]() |
| 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. | |