PHP对象与数组
我有一个neural network的PHP对象,我必须迭代并执行一些math的庞大数量。 我想知道如果我会更好地使用类关联的实例的关联数组?
我正在处理大约3640
对象,并且最多重复500
次(顶多),所以任何微型优化都有很大的帮助。 做$object['value']
比$object->value
不可避免会更快吗?
编辑:所以他们都是一样的。 但是我想这个构造函数会有一些额外的开销吗? 无论哪种方式,我不认为我想在我的漂亮的类中交换脏数组:P
基于Quazzle的代码,我运行了下一个代码(5.4.16 Windows 64位):
<?php class SomeClass { public $aaa; public $bbb; public $ccc; } function p($i) { echo '<pre>'; print_r($i); echo '</pre>'; } $t0 = microtime(true); $arraysOf=array(); $inicio=memory_get_usage(); for ($i=0; $i<1000; $i++) { $z = array(); for ($j=0; $j<1000; $j++) { $z['aaa'] = 'aaa'; $z['bbb'] = 'bbb'; $z['ccc'] = $z['aaa'].$z['bbb']; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>arrays: '.(microtime(true) - $t0)."</p>"; echo '<p>memory: '.($fin-$inicio)."</p>"; p($z); $t0 = microtime(true); $arraysOf=array(); $inicio=memory_get_usage(); for ($i=0; $i<1000; $i++) { $z = new SomeClass(); for ($j=0; $j<1000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>arrays: '.(microtime(true) - $t0)."</p>"; echo '<p>memory: '.($fin-$inicio)."</p>"; p($z); $t0 = microtime(true); $arraysOf=array(); $inicio=memory_get_usage(); for ($i=0; $i<1000; $i++) { $z = new stdClass(); for ($j=0; $j<1000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>arrays: '.(microtime(true) - $t0)."</p>"; echo '<p>memory: '.($fin-$inicio)."</p>"; p($z); ?>
我获得了下一个结果:
arrays: 1.8451430797577 memory: 460416 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 1.8294548988342 memory: 275696 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 2.2577090263367 memory: 483648 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
结论为PHP 5.4
- class级比数组快(但很less)。
- stdClass是邪恶的。
- 类比arrays使用更less的内存。 (约减less30-40%!!)
ps:作为一个说明,如果这个类是定义的,但是这个成员那么这个类的使用比较慢。 它也使用更多的内存。 显然秘密是定义成员
更新
我从php 5.4更新到php 5.5(5.5.12 x86窗口)。
arrays: 1.6465699672699 memory: 460400 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 1.8687851428986 memory: 363704 SplFixedArray Object ( [0] => aaa [1] => bbb [2] => aaabbb ) arrays: 1.8554251194 memory: 275568 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 2.0101680755615 memory: 483656 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
结论为PHP 5.5
- 对于数组来说,PHP 5.5比PHP 5.4快,因为对象几乎是一样的
- 由于PHP 5.5和数组的优化,Class比Arrays慢。
- stdClass是邪恶的。
- 类仍然使用比arrays更less的内存。 (约减less30-40%!!)。
- SplFixedArray类似于使用一个类,但它使用更多的内存。
我使用这个代码进行“性能分析”(1000个实例,1000,000次读/写):
function p($i) { echo '<pre>'; print_r($i); echo '</pre>'; } $t0 = microtime(true); for ($i=0; $i<1000; $i++) { $z = array(); for ($j=0; $j<1000; $j++) { $z['aaa'] = 'aaa'; $z['bbb'] = 'bbb'; $z['ccc'] = $z['aaa'].$z['bbb']; } } echo '<p>arrays: '.(microtime(true) - $t0); p($z); $t0 = microtime(true); for ($i=0; $i<1000; $i++) { $z = (object) null; for ($j=0; $j<1000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } } echo '<p>obj: '.(microtime(true) - $t0); p($z); echo '<p> phpversion '.phpversion();
它输出在我的LINUX托pipe这个东西:
arrays: 1.1085488796234 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) obj: 1.2824709415436 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) phpversion 5.2.17
所以得出的结论是: 即使在PHP 5.2上,对象也是比较慢的。 除非你真的需要他们的oopfunction,否则不要使用对象。
你没有向我们展示$object->value
如何工作的代码,因为它可能是后端它是一个数组,在这种情况下理论上使用数组会更快,因为它涉及less一个函数调用。 与函数调用相比,执行查找的代价可能会很大。 如果它是一个variables,那么在PHP中的对象和数组会有非常相似的实现。
如果你正在寻找优化,你将需要configuration文件来检查大部分时间正在使用。 我怀疑把对象改成数组不会有太大的区别。
您可以随时查看微软性能特征的PHP源代码。
但是乍看之下,即使只是一个散列表查找应该是O(1),PHP也不需要做['value'],因为PHP需要做一个Lookup查找['value'],这是不能保证的。 当使用Text-index时,会有更多的开销。
如果对象只包含1个需要访问的variables(值是value),则使用对象时会有更多的开销。
我看到这是一个旧的post,所以我想我会更新它。 这里是我的代码和统计,在Zend CE上完成5.3.21我尝试testing整个事情,存储信息并将其拉回。
V1:需要0.83秒
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a[0]; $b = $a[1]; } function get_one() { return array(1,1); }
V2:需要3.05秒
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a->v; $b = $a->k; } function get_one() { $ret = new test(); $ret->v = 1; $reb->k = 1; return $ret; } class test { public $v; public $k; }
V3:需要1.98秒(注意构造函数提高了性能)
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a->v; $b = $a->k; } function get_one() { return new test(1,1); } class test { public $v; public $k; public function __construct($v, $k) { $this->v = $v; $this->k = $k; } }
如果数组和类是相同的性能,我认为使用预定义类的对象来存储/传递业务数据将使我们的程序更多的逻辑和代码更易读。
今天,像Eclipse,Netbean这样的现代化的ide …知道一个对象(预定义的类)正在传递什么信息是非常方便的,但是数组并不是这样
例如:用数组
function registerCourse(array $student) { // Right here I don't know how a $student look like unless doing a print_r() or var_dump() .... }
与对象
class Studen { private $_name, $_age; public function getAge() {} public function getName() {} .. } function registerCourse(Studen $student) { // Right here I just Ctrl+Space $student or click "Student" and I know I can get name or age from it ... }
我使用php 7.0.9下的magallanes代码:
arrays: 0.19802498817444 memory: 324672 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.18602299690247 memory: 132376 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.1950249671936 memory: 348296 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
和用户的PHP 7.1.3:
arrays: 0.59932994842529 memory: 444920 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.72895789146423 memory: 164512 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.61777496337891 memory: 484416 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )