Что лучше использовать в 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-массив (написанный до того, как этот вопрос был опубликован), и теперь один из них использует класс, и я должен сказать, что класс производит гораздо более приятный код. Я не знаю, сколько накладных расходов будет создано, но я сомневаюсь, что это будет соперничать с улучшением самого кода.
Спасибо, что помогли сделать меня лучшим программистом.
«Класс», который вы создали выше, – это то, что большинство людей будет использовать структуру для других языков. Я не уверен, что последствия производительности в PHP, хотя я подозреваю, что создание экземпляров объектов, вероятно, будет более дорогостоящим здесь, хотя бы немного.
При этом, если стоимость относительно низкая, немного проще управлять объектами, на мой взгляд.
Я только говорю следующее на основе названия и вашего вопроса, но: Имейте в виду, что классы обеспечивают преимущество методов и контроля доступа. Поэтому, если вы хотите, чтобы люди не меняли весы на отрицательные числа, вы могли бы сделать поле weight
частным и предоставить некоторые методы доступа, такие как getWeight()
и setWeight()
. Внутри setWeight()
вы можете выполнить некоторую проверку значений, например:
public function setWeight($weight) { if($weight >= 0) { $this->weight = $weight; } else { // Handle this scenario however you like } }
Это зависит от того, что вы подразумеваете под «лучше». Я бы пошел объектно-ориентированным способом (используя классы), потому что считаю, что он делает более чистый код (по крайней мере, на мой взгляд). Тем не менее, я не уверен, какими будут штрафы за скорость для этого варианта.
Как правило, я следую этому правилу:
1) Сделайте его классом, если несколько частей приложения используют структуру данных.
2) Сделайте 2D-массив, если вы используете его для быстрой обработки данных в одной части вашего приложения.
Это скорость, о которой я думаю в основном, для чего-то более сложного, чем то, что у меня здесь, я бы, вероятно, пошел с классами, но вопрос в том, какова стоимость класса?
Казалось бы, это преждевременная оптимизация. Ваше приложение не будет принимать ни одного реального эффекта производительности в любом случае, но использование класса позволяет использовать методы getter и setter и, как правило, будет лучше для инкапсуляции кода и повторного использования кода.
С помощью массивов, которые вы затрачиваете на более сложное чтение и поддержание кода, вы не можете легко тестировать код, и с хорошей структурой классов другим разработчикам должно быть легче понять, нужно ли им их принимать.
И когда позже вам нужно добавить другие методы для их управления, у вас не будет расширения архитектуры.
Класс, который у вас есть, не является реальным классом в терминах OO – его только что удалось переместить в пространство переменных экземпляра.
Тем не менее – там, возможно, не так много проблем со скоростью – это просто стиль в вашем примере.
Интересный бит – это если вы решили, что объект будет настоящим классом «человек», и подумайте о других атрибутах и действиях, которые вы можете пожелать для класса человека, – тогда вы заметите не только стиль исполнения – код написания, но и тоже скорость производительность.
Если ваш код использует множество функций, которые работают с этими атрибутами (имя / высота / вес), то использование класса может быть хорошим вариантом.
Teifion, если вы используете классы в качестве простой замены для массивов, вы нигде не приближаетесь к ООП. Суть ООП заключается в том, что объекты обладают знаниями и ответственностью, могут фактически делать что-то и сотрудничать с другими классами. Ваши объекты имеют только знания и не могут делать ничего, кроме ленивого существования, однако они кажутся хорошими кандидатами для поставщиков персистентности (объекты, которые знают, как хранить / извлекать себя в / из базы данных).
Не беспокойтесь и о производительности. Объекты в 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']); } //------------------------------------- ?>
test reads: 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.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.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.9700801372528 (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 итераций)