PHP 对象与数组——迭代时的性能比较
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2193049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP Objects vs Arrays -- Performance comparison while iterating
提问by Louis
I have a huge amount of PHP objects for a neural network for which I have to iterate over and perform some maths on. I was wondering if I would be better off using an associative array over instances of classes?
我有大量用于神经网络的 PHP 对象,我必须对其进行迭代并执行一些数学运算。我想知道在类的实例上使用关联数组是否会更好?
I am dealing with around 3640objects and iterating around 500times (at best) on top of that so any micro-optimization helps a great deal. Would it inevitably be quicker to do $object['value']than $object->value?
我正在处理周围的3640对象并500在此之上迭代(最多),因此任何微优化都有很大帮助。它不可避免地会$object['value']比做更快$object->value吗?
Edit:So they are both the same. But I guess there would be a little overhead for the constructor? Either way I don't think I want to trade in my beautiful classes for dirty arrays :P
编辑:所以他们都是一样的。但我想构造函数会有一点开销?无论哪种方式,我都不认为我想用漂亮的类来交换脏数组:P
回答by magallanes
Based in the code of Quazzle, i ran the next code (5.4.16 windows 64bits):
基于Quazzle的代码,我运行了下一个代码(5.4.16 windows 64bits):
<?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);
?>
And i obtained the next result:
我得到了下一个结果:
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
)
Conclusion for php 5.4
php 5.4 的结论
- Class is fasts than Arrays (but marginally).
- stdClass is evil.
- Class uses less memory than Arrays. (about 30-40% less!!)
- Class 比 Arrays 快(但差一点)。
- stdClass 是邪恶的。
- 类比数组使用更少的内存。(减少约 30-40% !!)
ps: as a note, if the class is defined but the members then, the use of this class is slower. It also uses more memory. Apparently the secret is to define the members
ps:注意,如果定义了类但是定义了成员,那么使用这个类会比较慢。它还使用更多内存。 显然秘密是定义成员
Update
更新
I updated from php 5.4 to php 5.5 (5.5.12 x86 windows).
我从 php 5.4 更新到 php 5.5 (5.5.12 x86 windows)。
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
)
Conclusion for php 5.5
php 5.5 的结论
- For arrays, PHP 5.5 is faster than PHP 5.4, for object it is pretty much the same
- Class is slower than Arrays thanks to the optimization of PHP 5.5 and arrays.
- stdClass is evil.
- Class still uses less memory than Arrays. (about 30-40% less!!).
- SplFixedArray is similar to use a Class but it uses more memory.
- 对于数组,PHP 5.5 比 PHP 5.4 快,对于对象,它几乎相同
- 由于 PHP 5.5 和数组的优化,类比数组慢。
- stdClass 是邪恶的。
- 类仍然比数组使用更少的内存。(减少约 30-40% !!)。
- SplFixedArray 类似于使用类,但它使用更多内存。
回答by Quazzle
I used this code for "profiling" (1000 instances, 1000.000 reads/writes):
我使用此代码进行“分析”(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();
It outputs in my LINUX hosting this stuff:
它在我的 LINUX 中输出托管这些东西:
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
so in a conclusion: objects are slower even on PHP 5.2. Don't use objects unless you really need their oop features.
所以总结一下:即使在 PHP 5.2 上,对象也会变慢。不要使用对象,除非你真的需要它们的 oop 特性。
回答by chariothy
I use magallanes' code under php 7.0.9 :
我在 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
)
And user php 7.1.3:
和用户 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
)
回答by Qcho
magallanes' script @ PHP 7.3.5
麦哲伦的脚本@ PHP 7.3.5
SomeClass Objectis fastest and lightest.Array1.32xspeed. 2.70xmemory.stdClass Object1.65xspeed. 2.94xmemory.
SomeClass Object是最快和最轻的。Array1.32 倍速度。2.70 倍内存。stdClass Object1.65 倍速度。2.94 倍内存。
Raw output:
原始输出:
arrays: 0.064794063568115
memory: 444920
Array (
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 0.048975944519043
memory: 164512
SomeClass Object (
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 0.081161022186279
memory: 484416
stdClass Object (
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
回答by Nir
I see this is kind of an old post so I thought I'll update it. here are my codes and stats, done on Zend CE 5.3.21 I tried to test the whole thing, storing info and pulling it back.
我看到这是一个旧帖子,所以我想我会更新它。这是我的代码和统计数据,在 Zend CE 5.3.21 上完成我试图测试整个事情,存储信息并将其拉回来。
V1 : takes 0.83 sec
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 : takes 3.05 sec
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 : takes 1.98 sec (note that the constructor improves the performance)
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;
}
}
回答by Yacoby
You haven't shown us the code for how $object->valueworks, as it could be that backend it is an array in which case theoreticallyusing an array would be faster as it involves one less function call. The cost of doing the lookup will probably be huge compared to the function call. If it is a variable, there is going to be very little diffrence as objects and arrays in PHP have a very similar implementation.
您还没有向我们展示如何$object->value工作的代码,因为后端可能是一个数组,在这种情况下,理论上使用数组会更快,因为它涉及的函数调用更少。与函数调用相比,执行查找的成本可能会很大。如果它是一个变量,则差别很小,因为 PHP 中的对象和数组具有非常相似的实现。
If you are looking at optimizations, you will need to profile to check where the majority of the time is being used. I suspect that changing objects to arrays will make no major difference.
如果您正在考虑优化,则需要进行分析以检查大部分时间都在何处使用。我怀疑将对象更改为数组不会产生重大影响。
回答by Filip Ekberg
You can always check the PHP-source code for micro-performance-features like that.
您可以随时查看 PHP 源代码以获取诸如此类的微性能功能。
But at a first glance, no doing ['value'] will not be faster because PHP needs to do a Lookup on where to find ['value'] even thougn a hashtable lookup should be O(1), that's not guaranteed. There's more overhead when you use Text-index.
但乍一看,不做 ['value'] 不会更快,因为 PHP 需要查找 ['value'] 的位置,即使哈希表查找应该是 O(1),这并不能保证。使用 Text-index 时会有更多开销。
If the object only contains 1 variables that you need to access which is value, there's more overhead in using an object.
如果对象只包含 1 个需要访问的变量,即值,则使用对象会产生更多开销。
回答by Maksud Aghayev
For anybody who is still interested in this question :) I ran Quazzle code on PHP 7.1 Ubuntu x64 and got this answer:
对于仍然对这个问题感兴趣的任何人:) 我在 PHP 7.1 Ubuntu x64 上运行了 Quazzle 代码并得到了这个答案:
arrays: 0.24848890304565
memory: 444920
Array
(
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 0.23238587379456
memory: 164512
SomeClass Object
(
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 0.24422693252563
memory: 484416
stdClass Object
(
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
Conclusion
结论
Array take 4(!) the memory than class object.
Class object marginally faster.
stdClass still evil? magallanes :)
数组比类对象占用4(!)的内存。
类对象稍微快一点。
stdClass 还是邪恶的?麦哲伦 :)
回答by trungnnh
If Arrays and Classs are the same performance, I think use objects of predefined classes for storing/passing business data would make our program more logic and the code more readability.
如果数组和类的性能相同,我认为使用预定义类的对象来存储/传递业务数据会使我们的程序更具逻辑性,代码更具可读性。
Today, with modern ide like Eclipse, Netbean ... it's very convenient to know what info an objects (of predefined class) is carrying but arrays are not so
今天,使用像 Eclipse、Netbean 这样的现代 ide ......知道一个对象(预定义类)携带的信息非常方便,但数组并非如此
Eg: With array
例如:使用数组
function registerCourse(array $student) {
// Right here I don't know how a $student look like unless doing a print_r() or var_dump()
....
}
With object
有对象
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
...
}

