Классы против 2D массивов - PullRequest
       27

Классы против 2D массивов

6 голосов
/ 23 августа 2008

Что лучше использовать в 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;

Если предположить, что кто-то не вышел и не показал, что занятия слишком медленные, похоже, что класс выигрывает.

Я не знаю, какой ответ я должен принять, потому что только что проголосовал за всех.


И теперь я написал две почти идентичные страницы, одна с использованием 2D-массива (написанного до того, как был опубликован этот вопрос), а теперь другая с использованием класса, и я должен сказать, что класс производит намного более приятный код. Я понятия не имею, сколько будет генерироваться служебных данных, но я сомневаюсь, что это может сравниться с улучшением самого кода.

Спасибо, что помогли мне стать лучшим программистом.

Ответы [ 9 ]

9 голосов
/ 23 августа 2008

«Класс», который вы создали выше, - это то, для чего большинство людей будет использовать struct для других языков. Я не уверен, что влияет на производительность в PHP, хотя я подозреваю, что создание экземпляров объектов здесь, вероятно, дороже, хотя бы немного.

При этом, если цена относительно низкая, управлять объектами, на мой взгляд, немного проще.

Я только говорю следующее, основываясь на названии и вашем вопросе, но: Имейте в виду, что классы также предоставляют преимущества методов и контроля доступа. Поэтому, если вы хотите, чтобы люди не меняли веса на отрицательные числа, вы можете сделать поле weight закрытым и предоставить некоторые методы доступа, такие как getWeight() и setWeight(). Внутри setWeight() вы можете выполнить некоторую проверку значений, например:

public function setWeight($weight)
{
    if($weight >= 0)
    {
        $this->weight = $weight;
    }
    else
    {
        // Handle this scenario however you like
    }
}
4 голосов
/ 23 августа 2008

Как правило, я следую этому правилу:

1) Сделайте его классом, если несколько частей вашего приложения используют структуру данных.

2) Сделайте его двумерным массивом, если вы используете его для быстрой обработки данных в одной части вашего приложения.

4 голосов
/ 23 августа 2008

Это зависит от того, что вы имеете в виду под «лучше». Я бы пошел на объектно-ориентированный путь (с использованием классов), потому что я считаю, что это делает для более чистого кода (по крайней мере, на мой взгляд). Однако я не уверен, какие могут быть штрафы за скорость для этого варианта.

3 голосов
/ 23 августа 2008

Это скорость, о которой я думаю в основном, для чего-то более сложного, чем то, что у меня здесь есть, я бы, наверное, пошел с классами, но вопрос в том, какова стоимость класса?

Это может показаться преждевременной оптимизацией. Ваше приложение не получит никакого реального снижения производительности в любом случае, но использование класса позволяет использовать методы getter и setter и, как правило, будет лучше для инкапсуляции кода и повторного использования кода.

С массивами, за которые вам труднее читать и обслуживать код, вы не можете так легко выполнить модульное тестирование кода, а с хорошей структурой классов другим разработчикам будет легче понять, нужно ли им это делать. .

И когда позже вам понадобится добавить другие методы для управления ими, у вас не будет расширения архитектуры.

2 голосов
/ 23 августа 2008

Класс, который у вас есть, не является реальным классом в терминах ОО - он просто создан для того, чтобы занимать пространство переменных экземпляра.

Тем не менее, вероятно, нет большой проблемы со скоростью - это просто стиль в вашем примере.

Интересный бит - это если вы сделали объект реальным классом "человек" - и подумаете о других атрибутах и ​​действиях, которые вам могут понадобиться для этого класса - тогда вы заметите не только исполнение стиля - написание код - но и скорость исполнения.

0 голосов
/ 04 ноября 2012

@ Ричард Варно

Я проверил ваш точный код (после исправления мелких ошибок) и получил результаты, отличные от вас. На моем PHP 5.3.17 много работали классы.

Время массива = 0,69054913520813 Время занятий = 1.1762700080872

Общее время массива (пока) = 0,69054508209229 (100 000 итераций) Общее время урока (пока) = 1,1762590408325 (100 000 итераций)

Время массива = 0.99001502990723 Время занятий = 1.22034907341

Общее время массива (пока) = 1.6805560588837 (100 000 итераций) Общее время урока (пока) = 2,3966031074524 (100 000 итераций)

Время массива = 0,99191808700562 Время занятий = 1,2245700359344

Общее время массива (пока) = 2.6724660396576 (100 000 итераций) Общее время урока (пока) = 3,6211669445038 (100 000 итераций)

Время массива = 0,9890251159668 Время занятий = 1.2246470451355

Общее время массива (пока) = 3,661484003067 (100 000 итераций) Общее время урока (пока) = 4,8458080291748 (100 000 итераций)

Время массива = 0.99573588371277 Время занятий = 1.1242771148682

Общее время массива (пока) = 4.6572148799896 (100 000 итераций) Общее время урока (пока) = 5,99700801372528 (100 000 итераций)

Время массива = 0,88518786430359 Время занятий = 1.1427340507507

Общее время массива (пока) = 5,5423986911774 (100 000 итераций) Общее время занятия (пока) = 7.1128082275391 (100 000 итераций)

Время массива = 0,87605404853821 Время занятий = 0,95899105072021

Общее время массива (пока) = 6,4184486865997 (100 000 итераций) Общее время занятий (пока) = 8.0717933177948 (100 000 итераций)

Время массива = 0,73414516448975 Время занятий = 1.0223190784454

Общее время массива (пока) = 7.1525888442993 (100 000 итераций) Общее время урока (пока) = 9,0941033363342 (100 000 итераций)

Время массива = 0,95230412483215 Время занятий = 1.059828042984

Общее время массива (пока) = 8.1048839092255 (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 итераций)

0 голосов
/ 31 декабря 2010

Большинство тестов, которые используют временные массивы против классов, только тестируют их экземпляры. Как только вы действительно начнете что-то делать с ними.

Я был "пуристом", который использовал только массивы, потому что производительность была НАСТОЛЬКО намного лучше. Я написал следующий код, чтобы оправдать себя, чтобы оправдать лишние хлопоты, связанные с отсутствием использования классов (даже если они проще для программиста)

Скажем так, я был ОЧЕНЬ удивлен результатами!

    <?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.61484408379 (100 000 итераций) Общее время урока (пока) = 2,34141416473 (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

0 голосов
/ 29 августа 2008

Teifion, если вы используете классы как простую замену массивов, вы не находитесь рядом с ООП. Суть ООП заключается в том, что объекты обладают знаниями и ответственностью, на самом деле могут что-то делать и взаимодействовать с другими классами. Ваши объекты имеют только знания и не могут делать ничего, кроме как в режиме бездействия, однако они, похоже, являются хорошими кандидатами для поставщиков сохраняемости (объектов, которые знают, как хранить / извлекать себя в / из базы данных).

Не беспокойтесь и о производительности. Объекты в PHP быстрые и легкие, а производительность в целом сильно переоценена. Дешевле сэкономить ваше время программиста, использующего правильный подход, чем сэкономить микросекунды в вашей программе с неясным, трудным для отладки и исправления фрагментом кода.

0 голосов
/ 23 августа 2008

Если в вашем коде используется множество функций, которые работают с этими атрибутами (имя / рост / вес), то использование класса может быть хорошим вариантом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...