Frage

Was ist in PHP besser zu verwenden, ein 2D-Array oder eine Klasse?Ich habe ein Beispiel dafür beigefügt, was ich damit meine.

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

Unter der Annahme, dass jemand nicht herauskommt und zeigt, dass der Unterricht zu langsam ist, sieht es so aus, als ob der Unterricht gewinnt.

Ich weiß nicht, welche Antwort ich akzeptieren soll. Ich habe sie alle positiv bewertet.


Und ich habe jetzt zwei nahezu identische Seiten geschrieben, eine unter Verwendung des 2D-Arrays (geschrieben, bevor diese Frage gepostet wurde) und eine andere unter Verwendung einer Klasse, und ich muss sagen, dass die Klasse viel schöneren Code erzeugt.Ich habe keine Ahnung, wie viel Overhead entstehen wird, aber ich bezweifle, dass er mit der Verbesserung des Codes selbst mithalten kann.

Vielen Dank, dass Sie mir geholfen haben, ein besserer Programmierer zu werden.

War es hilfreich?

Lösung

Die „Klasse“, die Sie oben konstruiert haben, ist das, was die meisten Leute verwenden würden Struktur für in anderen Sprachen.Ich bin mir nicht sicher, welche Auswirkungen dies auf die Leistung in PHP hat, obwohl ich vermute, dass die Instanziierung der Objekte hier wahrscheinlich teurer ist, wenn auch nur geringfügig.

Allerdings ist es meiner Meinung nach etwas einfacher, die Objekte zu verwalten, wenn die Kosten relativ niedrig sind.

Ich sage nur aufgrund des Titels und Ihrer Frage Folgendes, aber:Bedenken Sie, dass Klassen auch den Vorteil von Methoden und Zugriffskontrolle bieten.Wenn Sie also sicherstellen möchten, dass die Gewichte nicht in negative Zahlen geändert werden, können Sie dies tun weight Feld privat und stellen Sie einige Zugriffsmethoden bereit, z getWeight() Und setWeight().Innen setWeight(), könnten Sie eine Wertprüfung durchführen, etwa so:

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

Andere Tipps

Es kommt genau darauf an, was Sie unter „besser“ verstehen.Ich würde mich für den objektorientierten Weg entscheiden (unter Verwendung von Klassen), weil ich finde, dass dadurch der Code sauberer wird (zumindest meiner Meinung nach).Allerdings bin ich mir nicht sicher, wie hoch die Geschwindigkeitseinbußen bei dieser Option sein könnten.

Generell halte ich mich an diese Regel:

1) Machen Sie daraus eine Klasse, wenn mehrere Teile Ihrer Anwendung die Datenstruktur verwenden.

2) Machen Sie daraus ein 2D-Array, wenn Sie es zur schnellen Verarbeitung von Daten in einem Teil Ihrer Anwendung verwenden.

Es ist die Geschwindigkeit, an die ich hauptsächlich denke. Für alles, was komplexer ist als das, was ich hier habe, würde ich wahrscheinlich Kurse nehmen, aber die Frage ist: Was kostet ein Kurs?

Dies scheint eine verfrühte Optimierung zu sein.Ihre Anwendung wird in keiner Weise einen realen Leistungseinbruch erleiden, aber die Verwendung einer Klasse ermöglicht die Verwendung von Getter- und Setter-Methoden und ist im Allgemeinen besser für die Codekapselung und Wiederverwendung von Code.

Durch die Arrays, die Ihnen Kosten verursachen, ist es schwieriger, den Code zu lesen und zu verwalten, Sie können den Code nicht so einfach Unit-Tests unterziehen und mit einer guten Klassenstruktur sollten es andere Entwickler einfacher finden, ihn zu verstehen, wenn sie ihn übernehmen müssen.

Und wenn Sie später andere Methoden hinzufügen müssen, um diese zu manipulieren, müssen Sie keine Architektur erweitern.

Die Klasse, die Sie haben, ist im Sinne von OO keine echte Klasse – sie wurde nur so konstruiert, dass sie den Platz der Instanzvariablen einnimmt.

Allerdings gibt es wahrscheinlich kein großes Problem mit der Geschwindigkeit – in Ihrem Beispiel ist es nur eine Stilsache.

Das Interessante daran ist, dass Sie, wenn Sie das Objekt als echte „Personen“-Klasse konstruieren und über die anderen Attribute und Aktionen nachdenken, die Sie möglicherweise von der Personenklasse erwarten, nicht nur eine Stilleistung bemerken würden – das Schreiben von Code –, sondern auch auch Geschwindigkeitsleistung.

Wenn Ihr Code viele Funktionen verwendet, die mit diesen Attributen (Name/Höhe/Gewicht) arbeiten, könnte die Verwendung von „class“ eine gute Option sein.

Teifion, wenn Sie Klassen als bloßen Ersatz für Arrays verwenden, sind Sie bei weitem nicht in der Nähe von OOP.Der Kern von OOP besteht darin, dass Objekte über Wissen und Verantwortung verfügen, tatsächlich Dinge tun und mit anderen Klassen zusammenarbeiten können.Ihre Objekte verfügen nur über Wissen und können nichts anderes tun, als untätig zu existieren. Sie scheinen jedoch gute Kandidaten für Persistenzanbieter zu sein (Objekte, die wissen, wie sie sich selbst in einer Datenbank speichern bzw. aus dieser abrufen).

Machen Sie sich auch keine Sorgen um die Leistung.Objekte in PHP sind schnell und leichtgewichtig und die Leistung wird im Allgemeinen stark überbewertet.Es ist billiger, als Programmierer mit dem richtigen Ansatz Zeit zu sparen, als Mikrosekunden in Ihrem Programm mit einem obskuren, schwer zu debuggenden und zu reparierenden Codestück einzusparen.

Die meisten Tests, die Arrays im Vergleich zu Klassen testen, testen nur deren Instanziierung.Sobald man tatsächlich anfängt, etwas damit zu machen.

Ich war ein „Purist“, der nur Arrays verwendete, weil die Leistung SO viel besser war.Ich habe den folgenden Code geschrieben, um mir selbst den zusätzlichen Aufwand zu rechtfertigen, der sich daraus ergibt, keine Klassen zu verwenden (auch wenn sie für den Programmierer einfacher sind).

Sagen wir es so: Ich war von den Ergebnissen SEHR überrascht!

    <?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 lautet:1 Testzuweisungen:1 Testkugel:1 Testfunktionen:1

Array -Zeit = 1,58905816078 Klassenzeit = 1.11980104446 Gesamtarray -Zeit (bisher) = 1,58903813362 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 1,11979603767 (100.000 Iterationen)

Array -Zeit = 1,02581000328 Klassenzeit = 1,22492313385 Gesamtarray -Zeit (bisher) = 2,61484408379 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 2,34471416473 (100.000 Iterationen)

Array -Zeit = 1,29942297935 Klassenzeit = 1,18844485283 Gesamtarray -Zeit (bisher) = 3,91425895691 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 3,5331492424 (100.000 Iterationen)

Array -Zeit = 1,28776097298 Klassenzeit = 1,02383089066 Gesamtarray -Zeit (bisher) = 5,2020149231 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 4,55697512627 (100.000 Iterationen)

Array -Zeit = 1,31235599518 Klassenzeit = 1,38880181313 Gesamtarray -Zeit (bisher) = 6,51436591148 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 5,94577097893 (100.000 Iterationen)

Array -Zeit = 1.3007349968 Klassenzeit = 1.07644081116 Gesamtarray -Zeit (bisher) = 7,81509685516 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 7,02220678329 (100.000 Iterationen)

Array -Zeit = 1.12752890587 Klassenzeit = 1.07106018066 Gesamtarray -Zeit (bisher) = 8,94262075424 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 8,09326195717 (100.000 Iterationen)

Array -Zeit = 1.08890199661 Klassenzeit = 1.09139609337 Gesamtarray -Zeit (bisher) = 10,0315177441 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 9,18465089798 (100.000 Iterationen)

Array -Zeit = 1,6172170639 Klassenzeit = 1,14714384079 Gesamtarray -Zeit (bisher) = 11.6487307549 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 10,3317887783 (100.000 Iterationen)

Array -Zeit = 1,53738498688 Klassenzeit = 1,28127002716 Gesamtarray -Zeit (bisher) = 13,1861097813 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 11.6130547523 (100.000 Iterationen)

GESAMTZEITEN:Gesamtarray -Zeit = 13.1861097813 (1.000.000 Iterationen) Gesamtklassenzeit = 11.6130547523 (1.000.000 Iterationen)

In beiden Fällen ist der Unterschied also ziemlich vernachlässigbar.Ich war sehr überrascht, als ich feststellte, dass der Unterricht tatsächlich etwas schneller wird, sobald man anfängt, global auf Dinge zuzugreifen.

Aber vertrauen Sie mir nicht, machen Sie es selbst.Ich persönlich fühle mich jetzt völlig frei von Schuldgefühlen, wenn es darum geht, Klassen in meinen Hochleistungsanwendungen zu verwenden.:D

@Richard Varno

Ich habe Ihren genauen Code ausgeführt (nachdem ich die kleinen Fehler behoben hatte) und ganz andere Ergebnisse erzielt als Sie.Bei meiner PHP 5.3.17-Installation liefen die Kurse häufig.

Array -Zeit = 0,69054913520813 Klassenzeit = 1,1762700080872

Gesamtarray -Zeit (bisher) = 0,69054508209229 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 1,1762590408325 (100.000 Iterationen)

Array -Zeit = 0,99001502990723 Klassenzeit = 1,22034907341

Gesamtarray -Zeit (bisher) = 1,6805560588837 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 2,3966031074524 (100.000 Iterationen)

Array -Zeit = 0,99191808700562 Klassenzeit = 1,2245700359344

Gesamtarray -Zeit (bisher) = 2,6724660396576 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 3,6211669445038 (100.000 Iterationen)

Array -Zeit = 0,9890251159668 Klassenzeit = 1,2246470451355

Gesamtarray -Zeit (bisher) = 3,661484003067 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 4,8458080291748 (100.000 Iterationen)

Array -Zeit = 0,99573588371277 Klassenzeit = 1,1242771148682

Gesamtarray -Zeit (bisher) = 4,6572148799896 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 5,9700801372528 (100.000 Iterationen)

Array -Zeit = 0,88518786430359 Klassenzeit = 1,1427340507507

Gesamtarray -Zeit (bisher) = 5,5423986911774 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 7,1128082275391 (100.000 Iterationen)

Array -Zeit = 0,87605404853821 Klassenzeit = 0,95899105072021

Gesamtarray -Zeit (bisher) = 6,4184486865997 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 8,0717933177948 (100.000 Iterationen)

Array -Zeit = 0,73414516448975 Klassenzeit = 1,0223190784454

Gesamtarray -Zeit (bisher) = 7,1525888442993 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 9.0941033333342 (100.000 Iterationen)

Array -Zeit = 0,95230412483215 Klassenzeit = 1,059828042984

Gesamtarray -Zeit (bisher) = 8,1048839092255 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 10,153927326202 (100.000 Iterationen)

Array -Zeit = 0,75814390182495 Klassenzeit = 0,84455919265747

Gesamtarray -Zeit (bisher) = 8,8630249500275 (100.000 Iterationen) Gesamtklassenzeit (bisher) = 10,998482465744 (100.000 Iterationen) Gesamtzeiten:

Gesamtarray -Zeit = 8,8630249500275 (1.000.000 Iterationen) Gesamtklassenzeit = 10,998482465744 (1.000.000 Iterationen)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top