Utilisation intelligente des variables globales ...

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 523 fois - Téléchargée 34 fois

Contenu du snippet

Salut à tous,
Ce code n'est pas vraiment un code à proprement parlé, mais plutôt une ébauche de tutoriel visant à expliquer l'interêt d'utilisation des variables globales. Je poste ça sur PHPCS parce que c'est un peu le seul langage que je connaisse vraiment bien, mais ce tutoriel est en fait valable pour l'integralité des langages de programmation existant.
Les variables globales servent souvent pour enregistrer des variables d'environnement que des classes ou des fonctions pourront récuperer et utiliser, voire modifier. Mais il existe également une autre utilisation de ces variables.
Elles peuvent en effet servir à optimiser certaines fonctions basée sur des boucles. Pour exemple, je vais utiliser 3 fonctions qui permettent de calculer le factoriel d'un entier n (rappel : n! = 1 * 2 * 3 * ... (n - 1) * (n). Pour info, ça peut aussi bien servir dans les probabilités que dans l'approximation de Pi ou de l'exponentiel ...).
La première fonction (factoriel_1) est récursive : elle s'appelle elle-même. J'ai pas trop la pédagogie nécessaire pour expliquer, alors je vous laisse comprendre .... Désolé. Mais c'est pas compliqué à comprendre !
La seconde fonction (factoriel_2) est barbare (dans le sens de "barbare logiquement"). Elle va calculer le factoriel à l'aide d'une boucle for, en multipliant une variable par elle même, etc ... Pareil, pas très compliqué à comprendre, c'est une fonction intuitive puisqu'elle suit notre pensée.
Enfin, la troisième fonction (factoriel_3) utilise les variables globales ...

Source / Exemple :


<?php
	// La fonction factorielle récursive ...
	function factoriel_1($n)
	{
		if ($n == 0)
		{
			return(1);
		}
		else 
		{ 
			return($n * factoriel_1($n - 1));
		}
	}
	// La fonction factorielle itérative...
	function factoriel_2($n)
	{
		$factoriel = 1;
		for ($i = 1; $i <= $n; $i++)
		{
			$factoriel *= $i;
		}
		return($factoriel);
	}
	// La fonction factorielle optimisée ...
	// On déclare d'abord le tableau qui va devenir global. Il contient en fait le résultat de 0! (factoriel de 0) = 1.
	$_factoriel = array('input' => 0, 'output' => 1);	
	function factoriel_3($n)
	{
		// On rend le tableau global ...
		global $_factoriel;
		// On regarde pour voir si la demande est la même que celle du tableau.
		if ($n == $_factoriel['input'])
		{
			// Si oui, on set la variable qui va être retournée avec la valeur du tableau global.
			$factoriel = $_factoriel['output'];
		}
		// On regarde maintenant si on va gagner du temps en utilisant le tableau global.
		elseif (abs($n - $_factoriel['input']) < $n)
		{
			// Si oui, les blocs suivants vont déterminés s'il faut décrémenter ou incrémenter pour acceder au factoriel voulu.
			$factoriel = $_factoriel['output'];
			if ($n - $_factoriel['input'] > 0)
			{ 
				for ($i = $_factoriel['input'] + 1; $i <= $n; $i++)
				{
					$factoriel = $factoriel * $i;
				}
			}
			else 
			{
				for ($i = $_factoriel['input']; $i >= $n + 1; $i--)
				{
					$factoriel = $factoriel / $i;
				}
			}
		}
		// Si ça ne vaut pas le coup, on calcule le factoriel de manière primaire.
		else
		{
			$factoriel = 1;
			for ($i = 1; $i <= $n; $i++)
			{
				$factoriel *= $i;
			}
		}
		// On update les globales pour l'utilsation suivante de la fonction.
		$_factoriel['input'] = $n;
		$_factoriel['output'] = $factoriel;
		return($factoriel);
	}

?>

Conclusion :


Bon, comme les fonctions sont mal expliquées, j'explique l'idée. En fait, les variables globales sont utilisées comme point de départ. En effet, dans l'exemple, pour calculer un factoriel, il faut partir de 1, puis executer la boucle jusqu'à n. A l'aide des globales, on peut maintenant partir du de la dernière valeure calculée, c'est à dire de la valeure calculée depuis la dernière fois où la fonction a été appellée ... Pas clair ?
On va utiliser une première fois la fonction pour calculer le factoriel de 5.
La fonction va faire une boucle, de 1 à 5.
Après le calcul, le tableau global va changer, et contenir '5' comme input et '120' dans 'output' (le factoriel de 5 vaut 120). Imaginons ensuite que le script doit ensuite calculer le factoriel de 7. Et bien, grâce au tableau, il n'aura pas à partir de 1, mais de 5 ! D'où un gain de temps et une optimisation non négligeable ! Voilà, j'espère que c'est un peu plus clair ...
Pour prouver ce que j'avance, des petits tests. J'ai calculé le factoriel de 12 nombre à la suite, avec chacune des fonctions. Et voilà le resultat :
factoriel_1 : 6.853ms
factoriel_2 : 9.211ms
factoriel_3 : 5.152ms
Convaincu ?
Il est bien entendu interessant d'utiliser ces variables spéciales uniquement si une fonction est souvent appellée, sinon ... Bon ... On peut s'en passer.
@ la prochaine !
++ !
LocalStone.

A voir également

Ajouter un commentaire Commentaires
cs_Kirua Messages postés 3006 Date d'inscription dimanche 14 avril 2002 Statut Membre Dernière intervention 31 décembre 2008
18 oct. 2004 à 17:43
les IOI ça me fait bien râler. En france ils ont un truc génial qui s'appelle ProLogin, qui est un organisme de préparation et de sélection des ados qui iront défendre la France pour les concours d'algorithmique. En Belgique, rien de tout ça :(

Je vois ce que tu veux dire pour la pile/file, c'est vrai qu'on peut le faire comme ça, et c'est en fait ce qu'on utilise pour des problèmes comme les N reines etc. J'y avais pas pensé, mais en fait on parcours bien un arbre virtuel, c'est bien vu ^^
cs_mehdibou Messages postés 365 Date d'inscription vendredi 24 mai 2002 Statut Membre Dernière intervention 18 octobre 2004
18 oct. 2004 à 16:41
He oui, Kirua, je te lis aussi, tu es une star ;)
(à quand une équipe de Belgique pour les IOI ?)

Et pour parcourir un arbre binaire sans fonction récursive, on peut se faire sa propre pile (en gros ça revient à faire un appel) pour une moitié et utiliser un while pour l'autre moitié, c'est assez barbare :)

Comme l'a dit Kirua, il vaut mieux utiliser un tableau complet indicé pour la fonction factorielle mais la méthode que tu montres (ne garder qu'une valeur) peut être intéressant si on est très limité en place et si les valeurs demandées sont assez proches (sinon ça revient quasiment à tout calculer et en pratique ça prendra même plus de temps), comme par exemple une courbe continue.
cs_Kirua Messages postés 3006 Date d'inscription dimanche 14 avril 2002 Statut Membre Dernière intervention 31 décembre 2008
18 oct. 2004 à 00:02
oki, content d'être lu :p

je vais me coucher à l'instant, bye bye ;)
LocalStone Messages postés 514 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 1 mars 2009
17 oct. 2004 à 23:53
Y a pas de mal, Kirua. En fait, je disais que ça faisait longtemps, parce que ça faisait longtemps que je n'avais pas lu un des tes commentaires, voilà tout.
++ !
cs_Kirua Messages postés 3006 Date d'inscription dimanche 14 avril 2002 Statut Membre Dernière intervention 31 décembre 2008
17 oct. 2004 à 18:35
dis ... je suis un peu gêné ... je viens de regarder les commentaires de tous tes codes pour voir où on aurait pu se croiser auparavant, parce que je me souviens pas de toi, ... dsl :D et j'ai pas trouvé où. tu me rafraîchis la mémoire? j'ai aussi regardé sur ts mes codes php, et rien ...

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.