1

Bonjour à tous,

Nous utilisons html2pdf pour générer des rapports relativement conséquents (une 50aine pour les plus simples, plus d'une 100aine pour les plus complexes). J'ai fréquemment dû augmenter l'ouverture mémoire de PHP (jusqu'à 512Mo !) pour pouvoir générer ces rapports. Dernièrement, la charge mémoire est montée crescendo jusqu'à ce qu'il soit impossible de supporter l'allocation mémoire nécessaire sur notre serveur.

J'ai fait une rapide analyse du code et j'ai pu localisé le problème du côté de PHP : la fonction preg_match_all() crée un **enorme!** tableau mémoire et gère (semble-t-il) très mal l'extraction des tags et des textes. Cette fonction est fréquemment suivie d'une boucle qui itère sur le tableau résultat et extrait des informations intéressantes pour html2pdf. J'ai donc fait un prototype en remplaçant preg_match_all + boucle par une structure while() qui itère directement sur les résultats d'un preg_match.

Les résultats sont pour l'instant très concluants : j'ai pu réduire sans problème l'ouverture mémoire à 128Mo (je testerai plus bas d'ici quelques jours) et le temps moyen d'exécution a été divisé par deux (pas de chiffres à l'appui : juste une impression).

Je vais généraliser la correction aux autres usages de preg_match_all(). Si la modification s'avère concluante et si vous êtes intéressés par le patch, merci de me faire signe que je vous envoie la classe modifiée.

Julien.

2

yop !

en effet, ca pourrait être interessant smile je suis prenneur

merci !

Spipu
Ancien pseudo : lolo

3

Voici la modification. Cela concerne parsingHTML.class.php, méthode searchCode.
Je n'ai pas constaté de regression pour l'instant ... Je pense qu'on doit pouvoir généraliser le principe aux trois preg_match_all() qui sont dans la méthode analiseCode mais j'avoue que je ne me suis pas creusé spécialement la tête à comprendre comment était interprétée l'expression rationnelle ...

tromb Fichier joint : parsingHTML.class.php

4

l'optimisation est pas mal, et ca permet de ne plus avoir un gros tableau créé temporairement.

pour les 3 autres preg_match_all, ils se limitent à l'analyse des propriétés d'une seule balise, leurs occupations mémoire et cpu sont négligeable normalement.
Ancien pseudo : lolo

5

Bug report !!!
if ($level==0) { $not = true; $end = true; } // si on est au niveau 0 : on a finit

Ya pas de 't' à "fini".
(Pour les crédits, je me contenterai de mon pseudo + adresse de mon skyblog) tripo

6

tu sors tongue


happy
Ancien pseudo : lolo

7

Dans mon cas de figure, en plus de l'économie de mémoire, je pense que le traitement séquentiel a permis une réduction des temps de traitement non négligeable !
Ravi d'avoir pu aider.

Julien.

8

je viens de faire des tests, ca améliore grandement si le fichier HTML à convertir est conséquent, mais pour de petits fichiers PDF, par contre, ca ralentit sad
Ancien pseudo : lolo

9

rectification.

j'ai fais pas mal de tests de charge, et j'ai du coup amélioré le parsing.

la méthode est maintenant la suivante :

		function searchCode($content, &$tmp)
		{
			// séparer les balises du texte
			$tmp = array();
			$reg = '/(<[^>]+>)|([^<]+)+/isU';

			// pour chaque élément trouvé :
			$str = '';
			$offset = 0;
			while(preg_match($reg, $content, $parse, PREG_OFFSET_CAPTURE, $offset))
			{
				// si une balise a été détectée
				if ($parse[1][0])
				{
					// sauvegarde du texte précédent si il existe
					if ($str!=='')	$tmp[] = array('txt',$str);
		
					// sauvegarde de la balise
					$tmp[] = array('code',trim($parse[1][0]));
					
					// initialisation du texte suivant
					$str = ''; 	
				}
				else
				{
					// ajout du texte à la fin de celui qui est déjà détecté
					$str.= $parse[2][0];
				}
				// Update offset to the end of the match
				$offset = $parse[0][1] + strlen($parse[0][0]);
				unset($parse);					
			}
			// si un texte est présent à la fin, on l'enregistre
			if ($str!='') $tmp[] = array('txt',$str);
			unset($str);
		}


sur un html de 65Ko à convertir :
- j'ai perdu 60ms sur 2300ms => 2% de perte de temps
- j'ai gagné 70ko sur 5700ko de mémoires utilisé à la fin du script=> 1% de gain
- je suis passé de 14000ko à 3200ko de mémoires utilisées pendant le parsing de l'html => 77% de gain happy
Ancien pseudo : lolo

10

La vache, gros progrès ! top

11

et tout ça simplement en virant un t dans un commentaire ?? ! trifus
dehors