2008-08-23 7 views
6

Quelle est la meilleure utilisation en PHP, un tableau 2D ou une classe? J'ai inclus un exemple de ce que je veux dire par là.Classes vs tableaux 2D

// Using a class 
class someClass 
{ 
    public $name; 
    public $height; 
    public $weight; 

    function __construct($name, $height, $weight) 
    { 
     $this -> name  = $name; 
     $this -> height = $height; 
     $this -> weight = $weight; 
    } 
} 

$classArray[1] = new someClass('Bob', 10, 20); 
$classArray[2] = new someClass('Fred', 15, 10); 
$classArray[3] = new someClass('Ned', 25, 30); 


// Using a 2D array 
$normalArray[1]['name'] = 'Bob'; 
$normalArray[1]['height'] = 10; 
$normalArray[1]['weight'] = 20; 

$normalArray[2]['name'] = 'Fred'; 
$normalArray[2]['height'] = 15; 
$normalArray[2]['weight'] = 10; 

$normalArray[3]['name'] = 'Ned'; 
$normalArray[3]['height'] = 25; 
$normalArray[3]['weight'] = 30; 

En supposant que quelqu'un ne vient pas et montrer que les classes sont trop lents, il ressemble à des victoires de classe.

Je ne sais pas quelle réponse je devrais accepter, je les ai tous mis à jour.


Et je l'ai maintenant écrit deux pages près identiques, en utilisant le tableau 2D (écrit avant cette question a été publiée) et maintenant une aide d'une classe et je dois dire que la classe produit un code beaucoup plus agréable. Je n'ai aucune idée de la quantité de coûts générés, mais je doute que cela puisse rivaliser avec l'amélioration du code lui-même.

Merci de contribuer à faire de moi un meilleur programmeur.

Répondre

9

La "classe" que vous avez construite ci-dessus est ce que la plupart des gens utiliseraient struct dans d'autres langues. Je ne suis pas sûr de ce que les implications de performance sont en PHP, bien que je soupçonne instanciation des objets est probablement plus coûteux ici, si ce n'est que d'un peu. Cela étant dit, si le coût est relativement faible, il est un peu plus facile de gérer les objets, à mon avis. Je ne fais que dire ce qui suit en fonction du titre et de votre question, mais: Gardez à l'esprit que les classes offrent l'avantage des méthodes et du contrôle d'accès. Donc, si vous vouliez vous assurer que les gens ne changeaient pas les poids en nombres négatifs, vous pourriez rendre le champ weight privé et fournir des méthodes d'accès, comme getWeight() et setWeight(). A l'intérieur setWeight(), vous pouvez faire quelques vérifications de valeur, comme suit:

public function setWeight($weight) 
{ 
    if($weight >= 0) 
    { 
     $this->weight = $weight; 
    } 
    else 
    { 
     // Handle this scenario however you like 
    } 
} 
4

Cela dépend exactement de ce que vous entendez par «mieux». J'irais pour la manière orientée objet (en utilisant des classes) parce que je trouve que cela rend le code plus propre (du moins à mon avis). Cependant, je ne suis pas sûr de ce que les pénalités de vitesse pourraient être pour cette option.

4

En général, je suivre cette règle:

1) Faire une classe si plusieurs parties de votre application utilisent la structure de données.

2) Faites-en un tableau 2D si vous l'utilisez pour un traitement rapide des données dans une partie de votre application.

3

Il est la vitesse que je pense à la plupart du temps, pour quelque chose de plus complexe que ce que j'ai ici, je serais probablement aller avec des classes, mais la question est, quel est le coût d'une classe?

Cela semble être l'optimisation prématurée. De toute façon, votre application ne sera pas affectée par les performances du monde réel, mais l'utilisation d'une classe vous permet d'utiliser les méthodes getter et setter et sera généralement meilleure pour l'encapsulation de code et la réutilisation de code.Avec les baies dont vous avez besoin pour lire et maintenir le code, vous ne pouvez pas tester le code aussi facilement et avec une bonne structure de classe. Les autres développeurs devraient le trouver plus facilement s'ils ont besoin de le prendre. sur.

Et quand plus tard, vous devrez ajouter d'autres méthodes pour les manipuler, vous n'aurez pas d'architecture à étendre.

2

La classe que vous avez n'est pas une vraie classe en termes d'OO - elle vient juste d'être conçue pour prendre l'espace des variables d'instance. Cela dit - il n'y a probablement pas beaucoup de problème avec la vitesse - c'est juste un truc de style dans votre exemple. Le bit intresting - si vous avez contsrtucted l'objet à être une véritable classe "person" - et penser aux autres attributs et actions que vous pouvez vouloir de la classe personne - alors vous remarquerez non seulement une performance de style - code d'écriture - mais aussi la performance de vitesse.

0

Si votre code utilise beaucoup de fonctions qui fonctionnent sur ces attributs (nom/taille/poids), l'utilisation de class pourrait être une bonne option.

0

Teifion, si vous utilisez des classes comme un simple remplacement pour les tableaux, vous n'êtes pas loin de la POO. L'essence de la POO est que les objets ont la connaissance et la responsabilité, peuvent réellement faire des choses et coopérer avec d'autres classes. Vos objets n'ont que des connaissances et ne peuvent rien faire d'autre qu'exister, cependant ils semblent être de bons candidats pour les fournisseurs de persistance (objets qui savent se stocker/se récupérer dans/depuis la base de données).

Ne vous inquiétez pas pour le rendement, aussi. Les objets en PHP sont rapides et légers et les performances en général sont beaucoup trop appréciées. Il est moins coûteux d'économiser votre temps en tant que programmeur en utilisant la bonne approche que d'enregistrer des microsecondes dans votre programme avec un morceau de code obscur, difficile à déboguer et à corriger.

0

La plupart des tests que les tableaux temporels par rapport aux classes testent uniquement en les instanciant. Une fois que vous commencez réellement à faire quelque chose avec eux.

J'étais un "puriste" qui n'utilisait que des baies car la performance était tellement meilleure. J'ai écrit le code suivant pour justifier à moi-même pour justifier les tracas supplémentaires de ne pas utiliser les classes (même si elles sont plus faciles sur le programmeur)

Disons simplement que j'ai été très surpris des résultats!

<?php 
$rx = ""; 
$rt = ""; 
$rf = ""; 

$ta = 0; // total array time 
$tc = 0; // total class time 

// flip these to test different attributes 
$test_globals = true; 
$test_functions = true; 
$test_assignments = true; 
$test_reads = true; 


// define class 


class TestObject 
{ 
    public $a; 
    public $b; 
    public $c; 
    public $d; 
    public $e; 
    public $f; 

    public function __construct($a,$b,$c,$d,$e,$f) 
    { 
    $this->a = $a; 
    $this->b = $b; 
    $this->c = $c; 
    $this->d = $d; 
    $this->e = $e; 
    $this->f = $f; 
    } 

    public function setAtoB() 
    { 
     $this->a = $this->b; 
    } 
} 

// begin test 

echo "<br>test reads: " . $test_reads; 
echo "<br>test assignments: " . $test_assignments; 
echo "<br>test globals: " . $test_globals; 
echo "<br>test functions: " . $test_functions; 
echo "<br>"; 

for ($z=0;$z<10;$z++) 
{ 
    $starta = microtime(true); 

    for ($x=0;$x<100000;$x++) 
    { 
     $xr = getArray('aaa','bbb','ccccccccc','ddddddddd','eeeeeeee','fffffffffff'); 

     if ($test_assignments) 
     { 
      $xr['e'] = "e"; 
      $xr['c'] = "sea biscut"; 
     } 

     if ($test_reads) 
     { 
      $rt = $x['b']; 
      $rx = $x['f']; 
     } 

     if ($test_functions) { setArrAtoB($xr); } 
     if ($test_globals) { $rf = glb_arr(); } 
    } 
    $ta = $ta + (microtime(true)-$starta); 
    echo "<br/>Array time = " . (microtime(true)-$starta) . "\n\n"; 


    $startc = microtime(true); 

    for ($x=0;$x<100000;$x++) 
    { 
     $xo = new TestObject('aaa','bbb','ccccccccc','ddddddddd','eeeeeeee','fffffffffff'); 

     if ($test_assignments) 
     { 
      $xo->e = "e"; 
      $xo->c = "sea biscut"; 
     } 

     if ($test_reads) 
     { 
      $rt = $xo->b; 
      $rx = $xo->f; 
     } 

     if ($test_functions) { $xo->setAtoB(); } 
     if ($test_globals) { $xf = glb_cls(); } 
    } 

    $tc = $tc + (microtime(true)-$startc); 
    echo "<br>Class time = " . (microtime(true)-$startc) . "\n\n"; 

    echo "<br>"; 
    echo "<br>Total Array time (so far) = " . $ta . "(100,000 iterations) \n\n"; 
    echo "<br>Total Class time (so far) = " . $tc . "(100,000 iterations) \n\n"; 
    echo "<br>"; 

} 
echo "TOTAL TIMES:"; 
echo "<br>"; 
echo "<br>Total Array time = " . $ta . "(1,000,000 iterations) \n\n"; 
echo "<br>Total Class time = " . $tc . "(1,000,000 iterations)\n\n"; 


// test functions 

function getArray($a,$b,$c,$d,$e,$f) 
{ 
    $arr = array(); 
    $arr['a'] = $a; 
    $arr['b'] = $b; 
    $arr['c'] = $c; 
    $arr['d'] = $d; 
    $arr['d'] = $e; 
    $arr['d'] = $f; 
    return($arr); 
} 

//------------------------------------- 

function setArrAtoB($r) 
{ 
    $r['a'] = $r['b']; 
} 

//------------------------------------- 

function glb_cls() 
{ 
    global $xo; 

    $xo->d = "ddxxdd"; 
    return ($xo->f); 
} 

//------------------------------------- 

function glb_arr() 
{ 
    global $xr; 

    $xr['d'] = "ddxxdd"; 
    return ($xr['f']); 
} 

//------------------------------------- 

?> 

test lit: 1 missions de test: 1 globals test: 1 fonctions de test: 1

temps Array = 1,58905816078 Classe temps = 1,11980104446 Temps total Array (jusqu'à présent) = 1,58903813362 (100.000 itérations) total du temps de classe (jusqu'à présent) = 1.11979603767 (100 000 itérations)

temps Array = 1,02581000328 classe temps = 1,22492313385 Le temps total de Array (jusqu'à présent) = 2.61484408379 (100 000 itérations) Durée totale de classe (jusqu'à présent) = 2.34471416473 (100 000 itérations)

temps Array = 1,29942297935 Classe temps = 1,18844485283 Temps total Array (jusqu'à présent) = 3.91425895691 (100 000 itérations) Durée totale de la classe (jusqu'à présent) = 3.5331492424 (100 000 itérations)

temps Array = 1,28776097298 Classe temps = 1,02383089066 Temps total de Array (jusqu'à présent) = 5.2020149231 (100 000 itérations) Durée totale de classe (jusqu'à présent) = 4.55697512627 (100 000 itérations)

temps Array = 1,31235599518 temps de classe = 1,38880181313 temps total de Array (jusqu'à présent) = 6.51436591148 (100 000 itérations) durée totale de classe (jusqu'à présent) = 5.94577097893 (100 000 itérations)

temps Array = 1,3007349968 Temps de classe = 1,07644081116 Temps total de Array (jusqu'à présent) = 7.81509685516 (100 000 itérations) Durée totale de classe (jusqu'à présent) = 7,02220678329 (100.000 itérations)

temps Array = 1,12752890587 Classe temps = 1,07106018066 Durée totale Array (jusqu'à présent) = 8.94262075424 (100 000 itérations) durée totale de classe (jusqu'à présent) = 8.09326195717 (100 000 itérations)

temps Array = 1,08890199661 classe temps = 1,09139609337 temps total de Array (jusqu'à présent) = 10,0315177441 (100.000 itérations) Temps total en classe (jusqu'à présent) = 9.18465089798 (100,000 ite rations)

temps Array = 1,6172170639 temps de classe = 1,14714384079 Temps total de Array (jusqu'à présent) = 11.6487307549 (100 000 itérations) Durée totale de classe (jusqu'à présent) = 10.3317887783 (100 000 itérations)

temps Array = 1,53738498688 temps de classe = 1,28127002716 temps total de Array (jusqu'à présent) = 13,1861097813 (100.000 itérations) durée totale de classe (jusqu'à présent) = 11,6130547523 (100.000 itérations)

tEMPS tOTAL: durée totale Array = 13,1861097813 (1 000 000 itérations) Temps total de la classe = 11,6130547523 (1 000 000 itérations)

Ainsi, dans les deux cas, la différence est négligeable. J'ai été très surpris de constater qu'une fois que vous commencez à accéder aux choses à l'échelle mondiale, les cours deviennent un peu plus rapides. Mais ne me fais pas confiance, fais-le pour toi-même. Personnellement, je me sens maintenant complètement libre de l'utilisation de cours dans mes applications hautes performances. : D

0

@Richard Varno

I Ran votre code exact (après fixé les petits bugs), et a obtenu des résultats bien différents que vous. Les cours fonctionnaient beaucoup sur mon installation de PHP 5.3.17.

temps Array = ,69054913520813 temps de classe = 1,1762700080872

Temps total de Array (jusqu'à présent) = 0.69054508209229 (100 000 itérations) Durée totale de classe (jusqu'à présent) = 1,1762590408325 (100.000 itérations)

temps Array = 0.99001502990723 Temps de classe = 1.22034907341

Temps total sur le module (jusqu'à présent) = 1.6805560588837 (100 000 itérations) Total du temps de classe (jusqu'à présent) = 2,3966031074524 (100.000 itérations)

temps Array = ,99191808700562 Classe temps = 1,2245700359344

Durée totale Array (jusqu'à présent) = 2.6724660396576 (100.000 itérations) temps total de classe (jusqu'à présent) = 3,6211669445038 (100.000 itérations)

temps Array = ,9890251159668 classe temps = 1,2246470451355

temps total Array (jusqu'à présent) = 3,66148400306 7 (100 000 itérations) Total du temps de classe (jusqu'à présent) = 4,8458080291748 (100.000 itérations)

temps Array = ,99573588371277 Classe temps = 1,1242771148682

Durée totale Array (jusqu'à présent) = 4.6572148799896 (100.000 itérations) temps total de classe (jusqu'à présent) = 5,9700801372528 (100.000 itérations)

temps Array = ,88518786430359 classe temps = 1,1427340507507

temps total Array (jusqu'à présent) = 5,5423986911774 (100 000 itérations) Durée totale de classe (jusqu'à présent) = 7,1128082275391 (100.000 itérations)

temps Array = ,87605404853821 temps de classe = ,95899105072021

Temps total de Array (jusqu'à présent) = 6,4184486865997 (100.000 itérations) Durée totale de classe (jusqu'à présent) = 8.0717933177948 (100.000 itérations)

temps Array = ,73414516448975 temps de classe = 1,0223190784454

temps total de Array (jusqu'à présent) = 7,1525888442993 (100 000 itération s) Durée totale de classe (jusqu'à présent) = 9,0941033363342 (100.000 itérations)

temps Array = ,95230412483215 temps de classe = 1,059828042984

Temps total de Array (jusqu'à présent) = 8,1048839092255 (100.000 itérations) Durée totale de classe (jusqu'à présent) = 10.153927326202 (100 000 itérations)

temps Array = ,75814390182495 classe temps = ,84455919265747

durée totale Array (jusqu'à présent) = 8.8630249500275 (100.000 itérations) Durée totale de classe (jusqu'à présent) = 10.998482465744 (100 000 itérations) TEMPS TOTAL:

Temps total = Array 8.8630249500275 (1000000 itérations) Temps total = Classe 10.998482465744 (1.000.000 itérations)