Pregunta

¿Qué es mejor usar en PHP, una matriz 2D o una clase?He incluido un ejemplo de lo que quiero decir con esto.

// 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;

Suponiendo que alguien no salga y demuestre que las clases son demasiado lentas, parece que la clase gana.

No tengo idea de qué respuesta debo aceptar. Simplemente las voté todas.


Y ahora he escrito dos páginas casi idénticas, una que usa la matriz 2D (escrita antes de que se publicara esta pregunta) y ahora otra que usa una clase y debo decir que la clase produce un código mucho mejor.No tengo idea de cuántos gastos generales se generarán, pero dudo que pueda rivalizar con la mejora del código en sí.

Gracias por ayudarme a convertirme en un mejor programador.

¿Fue útil?

Solución

La "clase" que ha construido anteriormente es lo que la mayoría de la gente usaría estructura para en otros idiomas.No estoy seguro de cuáles son las implicaciones de rendimiento en PHP, aunque sospecho que crear instancias de los objetos probablemente sea más costoso aquí, aunque solo sea un poco.

Dicho esto, si el costo es relativamente bajo, en mi opinión, ES un poco más fácil administrar los objetos.

Solo digo lo siguiente según el título y tu pregunta, pero:Tenga en cuenta que las clases también brindan la ventaja de los métodos y el control de acceso.Entonces, si quisieras asegurarte de que las personas no cambiaran los pesos a números negativos, podrías hacer el weight campo privado y proporcionar algunos métodos de acceso, como getWeight() y setWeight().Adentro setWeight(), podrías hacer algunas comprobaciones de valores, así:

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

Otros consejos

Depende exactamente de lo que quieras decir con "mejor".Yo optaría por la forma orientada a objetos (usando clases) porque creo que genera un código más limpio (al menos en mi opinión).Sin embargo, no estoy seguro de cuáles podrían ser las penalizaciones de velocidad para esa opción.

Generalmente sigo esta regla:

1) Conviértalo en una clase si varias partes de su aplicación utilizan la estructura de datos.

2) Conviértalo en una matriz 2D si la está utilizando para el procesamiento rápido de datos en una parte de su aplicación.

Es en la velocidad en lo que estoy pensando principalmente, para algo más complejo que lo que tengo aquí probablemente elegiría clases, pero la pregunta es, ¿cuál es el costo de una clase?

Esto parecería una optimización prematura.Su aplicación no sufrirá ningún impacto en el rendimiento del mundo real de ninguna manera, pero el uso de una clase le permite usar métodos getter y setter y, en general, será mejor para la encapsulación y reutilización de código.

Con las matrices en las que está incurriendo en costos de código más difícil de leer y mantener, no puede realizar pruebas unitarias del código tan fácilmente y con una buena estructura de clases, a otros desarrolladores les resultará más fácil de entender si necesitan asumirlo.

Y cuando más adelante necesite agregar otros métodos para manipularlos, no tendrá una arquitectura que ampliar.

La clase que tiene no es una clase real en términos de OO; simplemente ha sido construida para ocupar el espacio de las variables de instancia.

Dicho esto, probablemente no haya mucho problema con la velocidad; en su ejemplo, es solo una cuestión de estilo.

Lo interesante es que si construyes el objeto como una clase de "persona" real y piensas en los otros atributos y acciones que puedas desear de la clase de persona, entonces notarás no sólo un rendimiento de estilo (escribir código) sino También acelera el rendimiento.

Si su código usa muchas funciones que operan con esos atributos (nombre/altura/peso), entonces usar clase podría ser una buena opción.

Teifion, si usas clases como un mero reemplazo de matrices, no estás ni cerca de la programación orientada a objetos.La esencia de la programación orientada a objetos es que los objetos tienen conocimiento y responsabilidad, pueden realmente hacer cosas y cooperar con otras clases.Sus objetos solo tienen conocimiento y no pueden hacer nada más que existir inactivamente; sin embargo, parecen ser buenos candidatos para proveedores de persistencia (objetos que saben cómo almacenarse/recuperarse a sí mismos en/desde una base de datos).

No se preocupe también por el rendimiento.Los objetos en PHP son rápidos y livianos y el rendimiento en general está muy sobrevalorado.Es más barato ahorrar tiempo como programador utilizando el enfoque correcto que ahorrar microsegundos en su programa con algún código oscuro, difícil de depurar y arreglar.

La mayoría de las pruebas que cronometran matrices versus clases solo prueban instanciarlas.Una vez que realmente empiezas a hacer algo con ellos.

Yo era un "purista" que usaba sólo matrices porque el rendimiento era MUCHO mejor.Escribí el siguiente código para justificar ante mí mismo la molestia adicional de no usar clases (aunque son más fáciles para el programador)

¡Digamos que me sorprendieron MUY los resultados!

    <?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']);
}

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

?>

la prueba dice:1 Asignaciones de prueba:1 Test Globals:1 Funciones de prueba:1

Tiempo de matriz = 1.58905816078 Tiempo de clase = 1.11980104446 Tiempo de matriz total (hasta ahora) = 1.58903813362 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 1.11979603767 (100,000 iteraciones)

Tiempo de matriz = 1.02581000328 Tiempo de clase = 1.22492313385 Tiempo de matriz total (hasta ahora) = 2.61484408379 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 2.34471416473 (100,000 iteraciones)

Tiempo de matriz = 1.29942297935 Tiempo de clase = 1.18844485283 Tiempo de matriz total (hasta ahora) = 3.91425895691 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 3.5331492424 (100,000 iteraciones)

Tiempo de matriz = 1.28776097298 Tiempo de clase = 1.02383089066 Tiempo de matriz total (hasta ahora) = 5.2020149231 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 4.55697512627 (100,000 iteraciones)

Tiempo de matriz = 1.312355599518 Tiempo de clase = 1.38880181313 Tiempo total de la matriz (hasta ahora) = 6.51436591148 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 5.945777097893 (100,000 iteraciones)

Tiempo de matriz = 1.30073499968 Tiempo de clase = 1.07644081116 Tiempo de matriz total (hasta ahora) = 7.81509685516 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 7.02220678329 (100,000 iteraciones)

Tiempo de matriz = 1.12752890587 Tiempo de clase = 1.07106018066 Tiempo de matriz total (hasta ahora) = 8.94262075424 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 8.09326195717 (100,000 iteraciones)

Tiempo de matriz = 1.08890199661 Tiempo de clase = 1.09139609337 Tiempo de matriz total (hasta ahora) = 10.03151774441 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 9.18465089798 (100,000 iteraciones)

Tiempo de matriz = 1.6172170639 Tiempo de clase = 1.14714384079 Tiempo de matriz total (hasta ahora) = 11.6487307549 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 10.33178877783 (100,000 iteraciones)

Tiempo de matriz = 1.53738498688 Tiempo de clase = 1.28127002716 Tiempo de matriz total (hasta ahora) = 13.1861097813 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 11.6130547523 (100,000 iteraciones)

TIEMPOS TOTALES:Tiempo total de la matriz = 13.1861097813 (1,000,000 de iteraciones) Tiempo de clase total = 11.6130547523 (1,000,000 de iteraciones)

Entonces, en cualquier caso, la diferencia es bastante insignificante.Me sorprendió mucho descubrir que una vez que empiezas a acceder a las cosas globalmente, las clases se vuelven un poco más rápidas.

Pero no confíes en mí, ejecútalo tú mismo.Personalmente, ahora me siento completamente libre de culpa por utilizar clases en mis aplicaciones de alto rendimiento.:D

@Richard Varno

Ejecuté su código exacto (después de corregir los pequeños errores) y obtuve resultados muy diferentes a los suyos.Las clases se ejecutaron mucho en mi instalación de PHP 5.3.17.

Tiempo de matriz = 0.69054913520813 Tiempo de clase = 1.1762700080872

Tiempo de matriz total (hasta ahora) = 0.69054508209229 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 1.1762590408325 (100,000 iteraciones)

Tiempo de matriz = 0.99001502990723 Tiempo de clase = 1.22034907341

Tiempo de matriz total (hasta ahora) = 1.6805560588837 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 2.3966031074524 (100,000 iteraciones)

Tiempo de matriz = 0.99191808700562 Tiempo de clase = 1.2245700359344

Tiempo de matriz total (hasta ahora) = 2.6724660396576 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 3.6211669445038 (100,000 iteraciones)

Tiempo de matriz = 0.9890251159668 Tiempo de clase = 1.2246470451355

Tiempo de matriz total (hasta ahora) = 3.661484003067 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 4.8458080291748 (100,000 iteraciones)

Tiempo de matriz = 0.99573588371277 Tiempo de clase = 1.1242771148682

Tiempo de matriz total (hasta ahora) = 4.65721487999896 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 5.9700801372528 (100,000 iteraciones)

Tiempo de matriz = 0.88518786430359 Tiempo de clase = 1.1427340507507

Tiempo de matriz total (hasta ahora) = 5.5423986911774 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 7.1128082275391 (100,000 iteraciones)

Tiempo de matriz = 0.87605404853821 Tiempo de clase = 0.95899105072021

Tiempo total de la matriz (hasta ahora) = 6.41844486865997 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 8.0717933177948 (100,000 iteraciones)

Tiempo de matriz = 0.73414516448975 Tiempo de clase = 1.0223190784454

Tiempo total de la matriz (hasta ahora) = 7.15258884442993 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 9.0941033363342 (100,000 iteraciones)

Tiempo de matriz = 0.95230412483215 Tiempo de clase = 1.059828042984

Tiempo de matriz total (hasta ahora) = 8.1048839092255 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 10.153927326202 (100,000 iteraciones)

Tiempo de matriz = 0.75814390182495 Tiempo de clase = 0.84455919265747

Tiempo de matriz total (hasta ahora) = 8.8630249500275 (100,000 iteraciones) Tiempo de clase total (hasta ahora) = 10.998482465744 (100,000 iteraciones) Tiempos totales:

Tiempo de matriz total = 8.8630249500275 (1,000,000 de iteraciones) Tiempo de clase total = 10.998482465744 (1,000,000 de iteraciones)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top