OVH Cloud OVH Cloud

Efficacite d'une fonction avec utilis ation d'un tableau ou d'un switch

7 réponses
Avatar
Sebastien
Bonjour,

Pour générer des dates littérales en fonction de la langue j'envoie à
une fonction un numéro correspondant au numéro du mois.

Je passe en même temps un identifiant de langue.

Mais je me suis rendu compte que je procédais de deux façons différentes
pour deux fonction semblables (jour du mois ou de la semaine, et mois)
pour une logique qui me semble être la même.

Voici les exemples simplifiés (pas de gestion des langues, ni des erreurs) :

<?php
/* Méthode Tableau */
function month_literal($month_num)
{
$months = array('01' => 'janvier', '02' => 'février', '03' => 'mars',
'04' => 'avril', '05' => 'mai', '06' => 'juin',
'07' => 'juillet', '08' => 'août', '09' => 'septembre', '10' =>
'octobre', '11' => 'novembre', '12' => 'décembre');

return $months[$month_num];
}
?>

<?php
/* Méthode Switch */
function month_literal($month_num)
{
switch($month_num)
{
case '01': $month = 'janvier';break;
case '02': $month = 'février';break;
case '03': $month = 'mars';break;
case '04': $month = 'mai';break;
case '05': $month = 'jeudi';break;
case '06': $month = 'juin';break;
case '07': $month = 'juillet';break;
case '08': $month = 'août';break;
case '09': $month = 'septembre';break;
case '10': $month = 'octobre';break;
case '11': $month = 'novembre';break;
case '12': $month = 'décembre';break;
}

return $month;
}
?>

Les deux fonctions ont exactement le même but et fonctionnent
parfaitement, mais l'une est-elle plus rapide que l'autre, ou plus
efficace d'un autre point de vue ? Et *pourquoi* ?

La même approche peut être envisagée pour la jours de la semaine en
décomposant une date 'datetime' de MySQL et en utilisant la fonction
date() de PHP. Dans mes fonctions il y a aussi une détection de la
langue (identifiant passé en argument) donc la méthode est dupliquée
pour chaque langue, mais n'est évidemment exécutée qu'une fois par appel.

Là encore pour fourcher en fonction de la langue j'ai le choix entre des
if ... elseif ou des switch, mais c'est un autre sujet (quoique).


Sébastien

7 réponses

Avatar
Olivier Miakinen

Voici les exemples simplifiés (pas de gestion des langues, ni des erreurs) :

<?php
/* Méthode Tableau */
function month_literal($month_num)
{
$months = array('01' => 'janvier', [...], '12' => 'décembre');

return $months[$month_num];
}
?>

<?php
/* Méthode Switch */
function month_literal($month_num)
{
switch($month_num)
{
case '01': $month = 'janvier';break;
[...]
case '12': $month = 'décembre';break;
}

return $month;
}
?>


La différence de performances entre ces deux méthodes devrait être
tellement minime que tu ne devrais pas avoir à t'en inquiéter (en
particulier si tu as ne serait-ce qu'un seul accès à une base de données).

Cela dit, tu peux peut-être encore gagner un chouïème de micropoil en
faisant ceci :

<?php
/* Méthode Tableau créé une seule fois */
$global_months = array('01' => 'janvier', [...], '12' => 'décembre');
function month_literal($month_num)
{
global $global_months;

return $global_months[$month_num];
}
?>

Bien entendu ce serait plus propre si on pouvait déclarer une constante
MONTHS de type tableau, mais malheureusement ce n'est pas le cas.


--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)

Avatar
Benoit F
La différence de performances entre ces deux méthodes devrait être
tellement minime que tu ne devrais pas avoir à t'en inquiéter ...


Oui, je suis pour écrire le moins de code possible, alors quand j'ai une
date au format timestamp (retrouné par la fonction timestamp() de mysql
par exemple) je préffére utilise la fonction strftime qui retoure la
date sous forme de chaine de caractère
voir : http://fr2.php.net/manual/fr/function.strftime.php

par exemple :
$mois = strftime("%B",$timestamp);

sinon en passant juste le mois :

function month_literal($month_num){
return strftime("%B",mktime(0,0,0,$month_num));
}

l'affichage se fait en fonction de la locale, donc pour avoir les mois
en Français, il faut mettre en début de script :
setlocale (LC_ALL, "FR-fr");


--
Benoit F.

Avatar
Sebastien
Merci de vos réponses.

Je vais opter pour la globale, mais maintenant je me demande ce qui va
consommer le plus de mémoire... Enfin c'est pour le plaisir de mégoter.

Quant à setlocale(LC_ALL, 'FR-fr'), c'est :
setlocale (LC_ALL, "fr_FR");
C'est le underscore qui change tout.

Je ne l'utilise pas car j'ai eu des hébergements où ça n'était pas
installé, mais c'est vrai que c'est pratique !


Sébastien
Avatar
Benoit F
Quant à setlocale(LC_ALL, 'FR-fr'), c'est :
setlocale (LC_ALL, "fr_FR");
C'est le underscore qui change tout.


Les noms de locale ont effectivement habituellement des underscore, sauf
que en php sous windows le setlocale prends en parametre un code à trois
lettres (ISO 3166-Alpha-3) et que si on met la locale "fr_FR" ça ne
marche pas.


--
Benoit F.

Avatar
Sebastien

Quant à setlocale(LC_ALL, 'FR-fr'), c'est :
setlocale (LC_ALL, "fr_FR");
C'est le underscore qui change tout.



Les noms de locale ont effectivement habituellement des underscore, sauf
que en php sous windows le setlocale prends en parametre un code à trois
lettres (ISO 3166-Alpha-3) et que si on met la locale "fr_FR" ça ne
marche pas.


Je ne le savais pas, désolé !

Cependant sur 2 hébergeurs Unix où j'ai testé, la version avec tirets ne
passe pas.

Donc si j'ai bien compris :

Unix :
<?php
setlocale (LC_ALL, "fr_FR");
?>

Windows :
<?php
setlocale (LC_ALL, "fra");
?>

C'est bien ça ?

Sébastien


Avatar
Benoit F
Cependant sur 2 hébergeurs Unix où j'ai testé, la version avec tirets ne
passe pas.
Unix :
setlocale (LC_ALL, "fr_FR");
Windows :
setlocale (LC_ALL, "fra");


Oui, "normalement" :-p rien de tel qu'un petit test avant pour être sûr.

--
Benoit F.

Avatar
Eric Demeester
dans (in) fr.comp.lang.php, Olivier Miakinen <om+
ecrivait (wrote) :

[tableau vs Switch]

La différence de performances entre ces deux méthodes devrait être
tellement minime que tu ne devrais pas avoir à t'en inquiéter (en
particulier si tu as ne serait-ce qu'un seul accès à une base de données).


Dans le cas évoqué, oui, mais s'il y avait (beaucoup) plus de valeurs
possibles, ça changerait un peu la donne je pense.

Pour le tableau, l'accès à une cellule est instantané mais il faut
prendre en compte le temps nécessaire à sa construction (affectation
préalable des valeurs aux indices), sachant que ce temps est constant en
fonction du nombre de valeurs à affecter.

Pour le switch, pas de temps d'initialisation, mais comme son traitement
se fait ligne par ligne jusqu'à tomber sur la valeur recherchée et le
break associé, s'il y a beaucoup de valeurs possibles, ça /peut/ être
/un peu/ plus lent.

D'accord, c'est du pinaillage :)

PS: désolé pour cette réponse très tardive risquant du coup sembler ne
surgir de nulle part, l'article initial ayant disparu des serveurs,
mais bien que très intéressé par ce groupe, je n'ai malheureusement
pas le temps de le lire régulièrement, alors je stocke en local et
je lis quand je peux...

--
Eric