CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[PHP] Optimisation possible ?

Thanhatos
Thanhatos
Niveau 39
19 décembre 2011 à 10:59:52

Bonjour, j'aimerais, si c'est possible, savoir si ce code est optimisable s'il vous plait.

// Tant qu'on trouve un double on relance le tirage.
while ( $num1 == $num2 OR $num1 == $num3 OR $num1 == $num4 OR $num1 == $num5 OR $num2 == $num3 OR $num2 == $num4 OR $num2 == $num5 OR $num3 == $num4 OR $num3 == $num5 OR $num4 == $num5 )
{
$num1 = rand(1,50);
$num2 = rand(1,50);
$num3 = rand(1,50);
$num4 = rand(1,50);
$num5 = rand(1,50);
}

La partie pour laquelle je me pose la question est bien sûr la longue suite de variables que je compare une à une pour vérifier qu'il n'y a pas de doublon.
Par curiosité je me demande si on peut écrire ça autrement, de façon plus courte et aussi simple.

Merci d'avance.

_skip
_skip
Niveau 10
19 décembre 2011 à 11:15:10

Un truc du genre, de tête :

$nums = array();
$keyIndex = array();

while( count($nums) < 5)
{
$random = rand(1,50);

if( isset($keyIndex[$random] ) )
continue;

$nums[] = $random;
$keyIndex[$random] = true;
}

Thanhatos
Thanhatos
Niveau 39
19 décembre 2011 à 11:25:27

Heuuuu... pour moi c'est pas du tout simple ce que tu me proposes là. ^^
Je comprends pas ce que ton code fait à vrai dire. :s

Si tu peux m'expliquer ça s'il te plait ? :rouge: :noob:

Je vois que tu mets en tableau les valeurs des 5 variables $numX, que tu as un autre tableau dont je ne comprends pas à quoi il sert.

Et ensuite je suis pas perdu, je comprends pas ce que ça fait. :doute:

chris_27
chris_27
Niveau 10
19 décembre 2011 à 11:34:47

Et si on jouait au jeu "que fait ce code ?" plutôt . :hap:

Étape numéro 1 :
À ton avis, à quoi sert la variable keyindex introduite par _skip ? :question:

Thanhatos
Thanhatos
Niveau 39
19 décembre 2011 à 12:14:59

Bon, d'après ce que je comprends :

- Les variable $nums et $KeyIndex sont des tableaux, vides au départ.
- On ouvre une boucle while ou tant qu'on a pas 5 $nums ça continue de boucler.
- Dans la boucle on sort un numéro du random.
- Si le numéro existe on continue. Mais là j'ai pas l'habitude de ce genre de truc donc je capte pas ce que fout le $KeyIndex. Enfin, disons plutôt que je pense qu'il sert à conserver la valeur pour être une clé de tableau.

Mais ça manque de commentaires...

Enfin, on colle $random en valeur pour le tableau $nums, et on fixe à true $KeyIndex[$random].

tbop2
tbop2
Niveau 10
19 décembre 2011 à 12:16:38

Moi j'aime pas optimiser un code quand je suis meme pas sur de savoir ce qu'il doit reellement faire.

C'est quoi le vrai objectif de ton code au juste ?
Non pas que je ne comprends pas ton algorithme ni ce qui se passe mais ca reste trop flou pour savoir si ce que tu fais est vraiment intelligent au lieu de tout simplement revoir le probleme de facon differente.... or ce qui manque c'est l'enonce du probleme la.

Thanhatos
Thanhatos
Niveau 39
19 décembre 2011 à 12:27:22

Ah pardon, je pensais l'avoir mis.

L'objectif est : Sortir 5 nombres, sans doublon.

tbop2
tbop2
Niveau 10
19 décembre 2011 à 12:28:28

Non ca j'ai compris, mais c'est vraiment le seul truc qu'on a a savoir ? Avant d'optimiser un code on tente d'optimiser l'algorithme autour.

Sinon c'est bon tu as compris l'exemple de _skip maintenant ?

Thanhatos
Thanhatos
Niveau 39
19 décembre 2011 à 12:40:16

Bah oui c'était tout. ^^
Ma curiosité me poussait à me demander comment j'aurais fait si j'avais dû faire la même chose mais avec 10 000 nombres.

On m'a donné ça aussi comme méthode :

<?php
function randperm($max) {
$perm = range(1,$max);
for($cpt = $max-1; $cpt > 0; $cpt--) {
$nb = rand(1,$cpt);
$tmp = $perm[$cpt];
$perm[$cpt] = $perm[$nb];
$perm[$nb] = $tmp;
}
return($perm);
}
$perm = randperm(50);
for($cpt = 1; $cpt < 6; $cpt++) {
echo ' '.$perm[$cpt]."<br />";
}
?>

Thanhatos
Thanhatos
Niveau 39
19 décembre 2011 à 12:43:30

Non, dans l'exemple donné j'ai du mal avec ça =>

if( isset($keyIndex[$random] ) )
continue;

$keyIndex[$random] = true;

Il colle à la variable la valeur true après le if. Je l'aurais mis avant.
Parce que $KeyIndex[$random] , il contient quoi au moment où le if se déclenche ?

tbop2
tbop2
Niveau 10
19 décembre 2011 à 13:27:39

Un boolean !

Si cette ligne retourne true ca veut dire que ce nombre a deja ete randommise donc on recommence la boucle sans se poser plus de questions. Sinon ca veut dire qu'il n'existe pas donc on concatene ce dernier avec le tableau de sortie nums et on met l'entree a keyIndex[random] a true.

Il y avait deux choses moches dans ta solution de depart :

- cote algorithmique tu devais TOUJOURS tout refaire si seulement un resultat avait un doublon. Ce sont des calculs refaient pour rien
- cote code, ton code etait assez fige (seulement 5 random possibles), et avec un while qui tient sur plusieurs lignes erk.

Ma solution finale serait par exemple de donner en parametre le nombre de tirages differents que tu veux recevoir en resultat, comme ca tu as vraiment un code dynamique que tu pourras reutiliser par la suite.

_skip
_skip
Niveau 10
19 décembre 2011 à 14:06:26

Ce qui est difficile à comprendre avec l'index, c'est que j'utilise un tableau PHP en sachant qu'au niveau structure de données c'est une map triée et pas réellement un array au sens C/C++/java.

$array = array();

isset( $array[5] ) //return false, la clé 5 n'existe pas;

$array[5] = 'choucroute'; //je la définis et je reteste

isset( $array[5] ) //return true, la clé 5 existe avec la valeur "choucroute";

Avoir une seule structure qui fait liste, map, pile et qui porte le nom de tableau, forcément ça porte à confusion!

Thanhatos
Thanhatos
Niveau 39
19 décembre 2011 à 15:07:00

D'accord. Merci à vous pour les explications. :)

deepblue
deepblue
Niveau 16
19 décembre 2011 à 23:47:40

<?php

$count = 0;
$nums = array();

while($count != 5) {
$rand = mt_rand(1, 50);

if(!in_array($rand, $nums)) {
$nums[] = $rand;
$count++;
}
}

Après 5000 intération sur le code de _skip et celui ci, il s'avère que c'est aussi rapide (ou aussi lent). Par contre, c'est un peu plus élégant à mon goût.

Thanhatos
Thanhatos
Niveau 39
20 décembre 2011 à 07:01:59

Merci pour la variante, que je comprends mieux d'ailleurs. :)

_skip
_skip
Niveau 10
20 décembre 2011 à 07:51:55

""Vous aussi, commandez dès aujourd'hui notre livre "les grands mystères de PHP" volume 5 pour la modique somme de dix-neuf euros quatre-vingts quinze hors taxe.""

Non sérieux je comprends absolument pas pourquoi un code qui fait 2500 vérifications par itération en moyenne est aussi rapide qu'un autre qui fait un simple accès à une clé sur une map ordonnée (qui au pire serait donc une implémentation en arbre voire une linkedhashmap).

Ca me conforte bien dans le peu d'estime que j'ai de ce langage.

deepblue
deepblue
Niveau 16
20 décembre 2011 à 09:00:47

Vous connaissez mal PHP du coup les seules choses que vous voyez ce sont les choses qui ne vous conviennent pas :/

tbop2
tbop2
Niveau 10
20 décembre 2011 à 09:34:01

Tres vraisemblablement parce que in_array a ete compile et optimise a l'avance au lieu de passer par des mecanismes paralleles en l'apparence plus intelligents.

PHP n'est pas toujours compilable et compile si je me rappelle bien, seuls certaines framework comme Zend le permettent non ? (question ouverte)

_skip
_skip
Niveau 10
20 décembre 2011 à 15:06:15

deepblue Voir le profil de deepblue
Posté le 20 décembre 2011 à 09:00:47 Avertir un administrateur
Vous connaissez mal PHP du coup les seules choses que vous voyez ce sont les choses qui ne vous conviennent pas :/

:d) C'est surtout que la documentation est rare ou inexistante sur tout ce qui devient un tant soit peu pointu en terme de performance.

godrik
godrik
Niveau 30
20 décembre 2011 à 18:54:56

On dirait que la difference est l'utilisation d'un tableau a la place d'un ABR. Certes un ABR a une complexite de O(log(n)) sur l'operation find, mais tres souvent la constante qui est cache dans la notation big-O est consequente.

Le tableau contient 5000 valeurs, qui sont des entiers de 32 bit (certainement). Ca represente de l'ordre de 20K octet qui tiennent parfaitement dans un cache L1. Maintenant, si l'ABR est implemente connement avec un arbre et deux pointeurs pour les fils qui ne sont pas stocke de facon continue en memoire. Tu te retrouve a devoir acceder une ligne de cache pour chaque access en memoire et la structure consomme 64 octets par valeur, ce qui est approximativement 320K octets qui ne tient pas en cache L1.

Je ne parle meme pas du fait que la cherche dans un tableau est tres adapte aux pipeline des processeurs et peut etre accelerer par les instructions vectoriel du processeur alors qu'un ABR ne l'est probablement pas.

Apres tout ca n'a peut etre rien a voir, et ca m'etonnerait que les hashmap de php soit aussi mal implementer que ca. Mais avoir une difference de complexite et avoir une difference de performance sont deux choses differentes, souvent correler, mais pas toujours.

Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Programmation
  • Création de sites web
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment