Pergunta

O que é melhor para usar em PHP, um array 2D ou uma classe?Incluí um exemplo do que quero dizer com isso.

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

Supondo que alguém não apareça e mostre que as aulas estão muito lentas, parece que a turma vence.

Não tenho ideia de qual resposta devo aceitar. Acabei de votar em todas elas.


E agora escrevi duas páginas quase idênticas, uma usando o array 2D (escrita antes da postagem desta pergunta) e agora outra usando uma classe e devo dizer que a classe produz um código muito melhor.Não tenho ideia de quanta sobrecarga será gerada, mas duvido que rivalize com a melhoria do próprio código.

Obrigado por ajudar a me tornar um programador melhor.

Foi útil?

Solução

A "classe" que você construiu acima é o que a maioria das pessoas usaria como estrutura para em outros idiomas.Não tenho certeza de quais são as implicações de desempenho no PHP, embora suspeite que instanciar os objetos seja provavelmente mais caro aqui, mesmo que apenas um pouco.

Dito isto, se o custo for relativamente baixo, fica um pouco mais fácil gerenciar os objetos, na minha opinião.

Só estou dizendo o seguinte com base no título e na sua pergunta, mas:Tenha em mente que as classes também oferecem a vantagem de métodos e controle de acesso.Então, se você quisesse garantir que as pessoas não alterassem os pesos para números negativos, você poderia fazer o weight campo private e fornece alguns métodos de acesso, como getWeight() e setWeight().Dentro setWeight(), você poderia fazer alguma verificação de valor, assim:

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

Outras dicas

Depende exatamente do que você quer dizer com 'melhor'.Eu optaria pelo método orientado a objetos (usando classes) porque acho que isso cria um código mais limpo (pelo menos na minha opinião).No entanto, não tenho certeza de quais seriam as penalidades de velocidade para essa opção.

Geralmente, sigo esta regra:

1) Torne-a uma classe se várias partes do seu aplicativo usarem a estrutura de dados.

2) Torne-o um array 2D se estiver usando-o para processamento rápido de dados em uma parte do seu aplicativo.

É na velocidade que estou pensando principalmente, para algo mais complexo do que o que tenho aqui provavelmente optaria pelas aulas, mas a questão é: qual é o custo de uma aula?

Isto parece ser uma otimização prematura.Seu aplicativo não sofrerá nenhum impacto no desempenho do mundo real de qualquer maneira, mas o uso de uma classe permite usar métodos getter e setter e geralmente será melhor para encapsulamento e reutilização de código.

Com as matrizes, você está incorrendo em custos mais difíceis de ler e manter o código, você não pode testar a unidade do código tão facilmente e com uma boa estrutura de classes, outros desenvolvedores devem achar mais fácil entender se precisarem aceitá-lo.

E quando mais tarde você precisar adicionar outros métodos para manipulá-los, não terá uma arquitetura para estender.

A classe que você possui não é uma classe real em termos de OO - ela apenas foi construída para ocupar o espaço das variáveis ​​de instância.

Dito isto - provavelmente não há muitos problemas com velocidade - é apenas uma questão de estilo no seu exemplo.

A parte interessante - é que se você construísse o objeto para ser uma classe "pessoa" real - e pensando sobre os outros atributos e ações que você pode querer da classe pessoa - então você notaria não apenas um desempenho de estilo - escrevendo código - mas também acelera o desempenho.

Se o seu código usa muitas funções que operam nesses atributos (nome/altura/peso), usar class pode ser uma boa opção.

Teifion, se você usar classes como um mero substituto para arrays, você não estará nem perto de OOP.A essência da OOP é que os objetos tenham conhecimento e responsabilidade, possam realmente fazer coisas e cooperar com outras classes.Seus objetos possuem apenas conhecimento e não podem fazer nada além de existir ociosamente; no entanto, eles parecem ser bons candidatos para provedores de persistência (objetos que sabem como armazenar/recuperar-se no/do banco de dados).

Não se preocupe com o desempenho também.Objetos em PHP são rápidos e leves e o desempenho em geral é superestimado.É mais barato economizar seu tempo como programador usando a abordagem correta do que economizar microssegundos em seu programa com algum código obscuro, difícil de depurar e corrigir.

A maioria dos testes que comparam matrizes de tempo versus classes apenas testa sua instanciação.Assim que você realmente começar a fazer algo com eles.

Eu era um "purista" que usava apenas arrays porque o desempenho era MUITO melhor.Eu escrevi o código a seguir para justificar para mim mesmo o incômodo extra de não usar classes (mesmo que sejam mais fáceis para o programador)

Digamos que fiquei MUITO surpreso com os 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']);
}

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

?>

leituras de teste:1 Testes de teste:1 Globals de teste:1 Funções de teste:1

Tempo de matriz = 1.58905816078 Tempo de classe = 1.11980104446 Tempo total da matriz (até agora) = 1.58903813362 (100.000 iterações) Tempo total da aula (até agora) = 1.11979603767 (100.000 iterações)

Tempo de matriz = 1.02581000328 Tempo de classe = 1.22492313385 Tempo total da matriz (até agora) = 2.61484408379 (100.000 iterações) Tempo total da aula (até agora) = 2.34471416473 (100.000 iterações)

Tempo de matriz = 1.29942297935 Tempo de classe = 1.18844485283 Tempo total da matriz (até agora) = 3.91425895691 (100.000 iterações) Tempo total da aula (até agora) = 3,5331492424 (100.000 iterações)

Tempo de matriz = 1.28776097298 Tempo de classe = 1.02383089066 Tempo total da matriz (até agora) = 5.2020149231 (100.000 iterações) Tempo total da aula (até agora) = 4.55697512627 (100.000 iterações)

Tempo de matriz = 1.31235599518 Tempo de classe = 1.38880181313 Tempo total da matriz (até agora) = 6.51436591148 (100.000 iterações) Tempo total da aula (até agora) = 5.94577097893 (100.000 iterações)

Tempo de matriz = 1.3007349968 Tempo de classe = 1.07644081116 Tempo total da matriz (até agora) = 7.81509685516 (100.000 iterações) Tempo total da aula (até agora) = 7.02220678329 (100.000 iterações)

Tempo de matriz = 1.12752890587 Tempo de classe = 1.07106018066 Tempo total da matriz (até agora) = 8.94262075424 (100.000 iterações) Tempo total da aula (até agora) = 8.09326195717 (100.000 iterações)

Tempo de matriz = 1.08890199661 Tempo de classe = 1.09139609337 Tempo total da matriz (até agora) = 10.0315177441 (100.000 iterações) Tempo total da aula (até agora) = 9.18465089798 (100.000 itens)

Tempo de matriz = 1.6172170639 Tempo de classe = 1.14714384079 Tempo total da matriz (até agora) = 11.6487307549 (100.000 iterações) Tempo total da aula (até agora) = 10.3317887783 (100.000 iterações)

Tempo de matriz = 1.53738498688 Tempo de classe = 1.28127002716 Tempo total da matriz (até agora) = 13.1861097813 (100.000 iterações) Tempo total da aula (até agora) = 11.6130547523 (100.000 iterações)

TEMPOS TOTAIS:Tempo total da matriz = 13.1861097813 (1.000.000 iterações) Tempo total da classe = 11.6130547523 (1.000.000 iterações)

Então, de qualquer forma, a diferença é bastante insignificante.Fiquei muito surpreso ao descobrir que quando você começa a acessar as coisas globalmente, as aulas ficam um pouco mais rápidas.

Mas não confie em mim, administre você mesmo.Pessoalmente, agora me sinto completamente livre de culpa por usar classes em meus aplicativos de alto desempenho.:D

@Richard Varno

Executei seu código exato (depois de corrigir os pequenos bugs) e obtive resultados muito diferentes dos seus.As aulas rodaram muito na minha instalação do PHP 5.3.17.

Tempo de matriz = 0,69054913520813 Tempo de classe = 1.1762700080872

Tempo total da matriz (até agora) = 0,69054508209229 (100.000 iterações) Tempo total da aula (até agora) = 1.1762590408325 (100.000 iterações)

Tempo de matriz = 0,99001502990723 Tempo de classe = 1.22034907341

Tempo total da matriz (até agora) = 1.6805560588837 (100.000 iterações) tempo total da aula (até agora) = 2.3966031074524 (100.000 iterações)

Tempo de matriz = 0,99191808700562 Tempo de classe = 1.2245700359344

Tempo total da matriz (até agora) = 2,6724660396576 (100.000 iterações) tempo de aula total (até agora) = 3.6211669445038 (100.000 iterações)

Tempo de matriz = 0,9890251159668 Tempo de classe = 1.2246470451355

Tempo total da matriz (até agora) = 3.661484003067 (100.000 iterações) tempo total da aula (até agora) = 4.8458080291748 (100.000 iterações)

Tempo de matriz = 0,99573588371277 Tempo de classe = 1.1242771148682

Tempo total da matriz (até agora) = 4.6572148799896 (100.000 iterações) Tempo total da aula (até agora) = 5.9700801372528 (100.000 iterações)

Tempo de matriz = 0,88518786430359 Tempo de classe = 1.1427340507507

Tempo total da matriz (até agora) = 5.5423986911774 (100.000 iterações) Tempo total da aula (até agora) = 7.1128082275391 (100.000 iterações)

Tempo de matriz = 0,87605404853821 Tempo de classe = 0,95899105072021

Tempo total da matriz (até agora) = 6.4184486865997 (100.000 iterações) Tempo total da aula (até agora) = 8.0717933177948 (100.000 iterações)

Tempo de matriz = 0,73414516448975 Tempo de classe = 1.0223190784454

Tempo total da matriz (até agora) = 7.1525888442993 (100.000 iterações) Tempo total da aula (até agora) = 9.0941033363342 (100.000 iterações)

Tempo de matriz = 0,95230412483215 Tempo de classe = 1.059828042984

Tempo total da matriz (até agora) = 8.1048839092255 (100.000 iterações) Tempo total da aula (até agora) = 10.153927326202 (100.000 iterações)

Tempo de matriz = 0,75814390182495 Tempo de classe = 0,84455919265747

Tempo total da matriz (até agora) = 8.8630249500275 (100.000 iterações) Tempo total da aula (até agora) = 10.998482465744 (100.000 iterações) Totões totais:

Tempo total da matriz = 8.8630249500275 (1.000.000 iterações) Tempo total da aula = 10.998482465744 (1.000.000 iterações)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top