質問

PHP では 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;

誰かが出てきて授業が遅すぎることを示さなければ、クラスが勝ったように見えます。

どの回答を受け入れるべきかわかりません。すべての回答に賛成票を投じたところです。


そして、私は今、ほぼ同じページを 2 つ書きました。1 つは 2D 配列を使用し (この質問が投稿される前に書かれました)、もう 1 つはクラスを使用しています。クラスはより優れたコードを生成すると言わざるを得ません。どれだけのオーバーヘッドが生成されるかわかりませんが、コード自体の改善に匹敵するものではないと思います。

私をより良いプログラマーに育ててくれてありがとう。

役に立ちましたか?

解決

上記で構築した「クラス」は、ほとんどの人が使用するものです。 構造体 他の言語の場合。PHP のパフォーマンスにどのような影響があるのか​​はわかりませんが、おそらくここではオブジェクトのインスタンス化の方が、わずかではあるにしてもコストがかかるのではないかと思います。

そうは言っても、コストが比較的低ければ、オブジェクトの管理は少し簡単になると私は思います。

タイトルと質問から判断して以下のことを言っているだけですが、クラスには、メソッドとアクセス制御の利点もあることに留意してください。したがって、人々が重みを負の数に変更しないようにしたい場合は、次のようにすることができます。 weight フィールドを private にし、次のようないくつかのアクセサー メソッドを提供します。 getWeight() そして setWeight(). 。内部 setWeight(), 、次のように値のチェックを行うことができます。

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

他のヒント

それは正確に「より良い」が何を意味するかによって異なります。私はオブジェクト指向の方法 (クラスを使用) を選びます。その方がコードがきれいになるからです (少なくとも私の意見では)。ただし、そのオプションで速度にどのようなペナルティが発生するかはわかりません。

通常、私は次のルールに従います。

1) アプリケーションの複数の部分でデータ構造を使用する場合は、それをクラスにします。

2) アプリケーションの一部でデータを迅速に処理するために使用する場合は、2D 配列にします。

私が主に考えているのは速度です。ここで説明したものよりも複雑な場合は、おそらくクラスを使用するでしょう。しかし問題は、クラスの費用はいくらかということです。

これは時期尚早の最適化であると思われます。どちらの方法でも、アプリケーションが実際のパフォーマンスに影響を与えることはありませんが、クラスを使用するとゲッター メソッドとセッター メソッドを使用できるため、一般にコードのカプセル化とコードの再利用が向上します。

配列を使用すると、コードの読み取りと保守が難しくなりコストが発生するため、コードの単体テストを簡単に行うことができません。また、適切なクラス構造があれば、他の開発者がコードを実行する必要がある場合でも理解しやすくなるはずです。

そして、後でこれらを操作するために他のメソッドを追加する必要がある場合、拡張するアーキテクチャがありません。

あなたが持っているクラスは、オブジェクト指向の用語では実際のクラスではありません。インスタンス変数のスペースを占有するために構築されただけです。

そうは言っても、速度に関してはおそらくそれほど問題はありません。あなたの例では、それは単なるスタイルの問題です。

興味深いのは、オブジェクトを実際の「person」クラスとして構築した場合、その person クラスに必要な他の属性やアクションについて考えると、スタイルのパフォーマンス (コードの作成) だけではなく、スピード性能も。

コードでこれらの属性 (名前/身長/体重) を操作する関数を多数使用する場合は、クラスを使用するのが良い選択肢になる可能性があります。

テイフィオンさん、クラスを配列の単なる置き換えとして使用する場合、OOP には程遠いです。OOP の本質は、オブジェクトが知識と責任を持ち、実際に何かを実行し、他のクラスと連携できることです。オブジェクトは知識のみを持ち、ただ存在すること以外は何もできませんが、永続化プロバイダー (データベースに自身を格納したりデータベースから取得したりする方法を知っているオブジェクト) としては適しているようです。

パフォーマンスについても心配する必要はありません。PHP のオブジェクトは高速かつ軽量であり、パフォーマンスは一般的に過大評価されています。難解でデバッグや修正が難しいコードを使用してプログラムのマイクロ秒を節約するよりも、適切なアプローチを使用してプログラマーとしての時間を節約する方がコストが安くなります。

配列とクラスを比較するテストのほとんどは、配列のインスタンス化のみをテストします。実際に彼らと一緒に何かを始めたら。

私はパフォーマンスがはるかに優れていたため、配列のみを使用する「純粋主義者」でした。クラスを使用しないことによる余分な手間を自分自身に正当化するために、次のコードを書きました(プログラマにとってはクラスの方が簡単ですが)。

この結果にはとても驚いたとだけ言っておきましょう。

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

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

?>

テスト読み取り:1テスト割り当て:1テストグローバル:1テスト関数:1

配列時間= 1.58905816078クラス時間= 1.11980104446合計配列時間(これまで)= 1.58903813362(100,000繰り返し)合計授業時間(これまでのところ)= 1.11979603767(100,000繰り返し)

配列時間= 1.02581000328クラス時間= 1.22492313385合計配列時間(これまでのところ)= 2.614844408379(100,000繰り返し)合計授業時間(これまでのところ)= 2.34471416473(100,000繰り返し)

配列時間= 1.29942297935クラス時間= 1.18844485283合計配列時間(これまで)= 3.91425895691(100,000回の繰り返し)合計授業時間(これまでのところ)= 3.5331492424(100,000反復)

配列時間= 1.28776097298クラス時間= 1.02383089066合計配列時間(これまでのところ)= 5.2020149231(100,000繰り返し)合計授業時間(これまでのところ)= 4.55697512627(100,000回の繰り返し)

配列時間= 1.31235599518クラス時間= 1.38880181313合計配列時間(これまで)= 6.51436591148(100,000反復)合計クラス時間(これまでのところ)= 5.94577097893(100,000反復)

配列時間= 1.3007349968クラス時間= 1.07644081116合計配列時間(これまで)= 7.81509685516(100,000回の反復)合計授業時間(これまでのところ)= 7.02220678329(100,000回の繰り返し)

配列時間= 1.12752890587クラス時間= 1.07106018066合計配列時間(これまで)= 8.94262075424(100,000回の反復)合計クラス時間(これまでのところ)= 8.09326195717(100,000回の繰り返し)

配列時間= 1.08890199661クラス時間= 1.09139609337合計配列時間(これまで)= 10.0315177441(100,000反復)合計授業時間(これまでのところ)= 9.18465089798(100,000反復)

配列時間= 1.6172170639クラス時間= 1.14714384079合計配列時間(これまで)= 11.6487307549(100,000回の繰り返し)合計クラス時間(これまでのところ)= 10.3317887783(100,000回の繰り返し)

アレイ時間= 1.53738498688クラス時間= 1.28127002716合計配列時間(これまで)= 13.1861097813(100,000繰り返し)合計授業時間(これまでのところ)= 11.6130547523(100,000回の繰り返し)

合計時間:合計配列時間= 13.1861097813(1,000,000の反復)合計クラス時間= 11.6130547523(1,000,000反復)

したがって、どちらの方法でも違いはほとんどありません。グローバルにアクセスし始めると、クラスが実際に少し速くなることを知って非常に驚きました。

しかし、私を信用しないで、自分自身のために実行してください。私自身、今では高性能アプリケーションでクラスを使用することにまったく罪悪感を感じていません。:D

@リチャード・ヴァルノ

私はあなたの正確なコードを実行しました(小さなバグを修正した後)、あなたとは大きく異なる結果が得られました。クラスは PHP 5.3.17 インストールでほとんど実行されました。

配列時間= 0.69054913520813クラス時間= 1.1762700080872

合計配列時間(これまで)= 0.69054508209229(100,000反復)合計クラス時間(これまで)= 1.1762590408325(100,000反復)

配列時間= 0.99001502990723クラス時間= 1.22034907341

合計配列時間(これまで)= 1.680560588837(100,000反復)合計クラス時間(これまでのところ)= 2.3966031074524(100,000反復)

配列時間= 0.99191808700562クラス時間= 1.2245700359344

合計配列時間(これまで)= 2.6724660396576(100,000反復)合計クラス時間(これまでのところ)= 3.62116694445038(100,000イテレーション)

配列時間= 0.9890251159668クラス時間= 1.2246470451355

合計配列時間(これまで)= 3.661484003067(100,000反復)合計クラス時間(これまでのところ)= 4.8458080291748(100,000イテレーション)

配列時間= 0.9957358371277クラス時間= 1.1242771148682

合計配列時間(これまで)= 4.6572148799896(100,000反復)合計クラス時間(これまでのところ)= 5.9700801372528(100,000反復)

配列時間= 0.88518786430359クラス時間= 1.1427340507507

合計配列時間(これまで)= 5.5423986911774(100,000反復)合計授業時間(これまで)= 7.1128082275391(100,000反復)

配列時間= 0.87605404853821クラス時間= 0.95899105072021

合計配列時間(これまで)= 6.418486865997(100,000反復)合計クラス時間(これまで)= 8.0717933177948(100,000反復)

配列時間= 0.73414516448975クラス時間= 1.0223190784454

合計配列時間(これまで)= 7.1525888442993(100,000反復)合計クラス時間(これまで)= 9.0941033363342(100,000反復)

配列時間= 0.95230412483215クラス時間= 1.059828042984

合計配列時間(これまで)= 8.104839092255(100,000反復)合計クラス時間(これまでのところ)= 10.153927326202(100,000イテレーション)

配列時間= 0.75814390182495クラス時間= 0.84455919265747

合計配列時間(これまで)= 8.8630249500275(100,000反復)合計クラス時間(これまでのところ)= 10.998482465744(100,000反復)合計時間:

合計配列時間= 8.8630249500275(1,000,000反復)合計クラス時間= 10.998482465744(1,000,000反復)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top