PHP对象与数组

Lou*_*uis 83 php arrays optimization object

我有一个神经网络的大量PHP对象,我必须迭代它并执行一些数学运算.我想知道我是否会更好地在类的实例上使用关联数组?

我正在处理周围的3640对象并在此基础上迭代500(最好),因此任何微优化都有很大帮助.它不可避免地会$object['value']比这更快$object->value吗?

编辑:所以他们都是一样的.但我想构造函数会有一点开销吗?无论哪种方式,我都不认为我想在我的漂亮类中交换脏数组:P

mag*_*nes 63

根据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);  
?>
Run Code Online (Sandbox Code Playgroud)

我获得了下一个结果:

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
)
Run Code Online (Sandbox Code Playgroud)

php 5.4的结论

  1. 类比阵列快(但是很少).
  2. stdClass是邪恶的.
  3. 类使用的内存少于数组.(减少约30-40%!!)

ps:作为注释,如果定义了类但是成员那么,这个类的使用速度较慢.它还使用更多内存. 显然,秘诀是定义成员

更新

我从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
)
Run Code Online (Sandbox Code Playgroud)

php 5.5的结论

  1. 对于数组,PHP 5.5比PHP 5.4更快,对于对象它几乎是相同的
  2. 由于PHP 5.5和数组的优化,类比Arrays慢.
  3. stdClass是邪恶的.
  4. 类仍然比Arrays使用更少的内存.(减少约30-40%!!).
  5. SplFixedArray类似于使用Class但它使用更多内存.

  • 使用PHP7,数组和对象之间的差异变得更加重要.您的脚本显示30%运行时和60%内存的差异.这只是我的机器,但作为一个经验法则:不要使用数组作为结构.改为使用对象:) (2认同)

小智 9

我使用此代码进行"分析"(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();
Run Code Online (Sandbox Code Playgroud)

它输出在我的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
Run Code Online (Sandbox Code Playgroud)

所以总结:即使在PHP 5.2上,对象也会变慢.除非你真的需要它们的oop功能,否则不要使用对象.

  • 来自用户levans http://stackoverflow.com/users/1473035/levans:我用5.3.8运行它,对象速度较慢,阵列为0.51839280128479,对象为0.85355806350708.我也在5.4.13运行它并得到了相反的结果,可能是由于5.4,6.6256799697876对阵列的类优化和0.43650078773499.因此看起来桌子已经转动,现在是对象. (7认同)

n0n*_*g0n 6

好吧,今天我对 @magallanes 基准感到好奇,所以我对其进行了一些扩展。我提高了一些 for 循环,以真正突出事物之间的差距。它在 Apache 2.4、mod_php 和 PHP 7.2 上运行。

这是一个汇总表,可以使结果更容易:

+---------------------------+---------+-----------------+
|           Test            | Memory  |      Time       |
+---------------------------+---------+-----------------+
| Array                     | 2305848 | 9.5637300014496 |
| stdClass                  | 2505824 | 11.212271928787 |
| SomeClass                 |  963640 | 11.558017015457 | <-- *
| AnotherClass              | 2563136 | 10.872401237488 |
| SetterClass               |  905848 | 59.879059791565 |
| SetterClassDefineReturn   |  905792 | 60.484427213669 |
| SetterClassSetFromParam   |  745792 | 62.783381223679 |
| SetterClassSetKeyAndParam |  745824 | 72.155715942383 |
+---------------------------+---------+-----------------+
* - Winner winner chicken dinner
Run Code Online (Sandbox Code Playgroud)

以下是修改后的脚本。我想测试使用方法设置属性和定义类型。我非常惊讶地发现使用 setter 方法会给代码带来显着的影响。现在承认这是一个非常非常具体的性能测试,许多应用程序甚至不会达到这个测试。但是,如果您的站点每秒处理 1000 个请求,其中有 1000 个类,这些类与 1000 个对象一起使用,您可以看到这对性能有何影响。

+---------------------------+---------+-----------------+
|           Test            | Memory  |      Time       |
+---------------------------+---------+-----------------+
| Array                     | 2305848 | 9.5637300014496 |
| stdClass                  | 2505824 | 11.212271928787 |
| SomeClass                 |  963640 | 11.558017015457 | <-- *
| AnotherClass              | 2563136 | 10.872401237488 |
| SetterClass               |  905848 | 59.879059791565 |
| SetterClassDefineReturn   |  905792 | 60.484427213669 |
| SetterClassSetFromParam   |  745792 | 62.783381223679 |
| SetterClassSetKeyAndParam |  745824 | 72.155715942383 |
+---------------------------+---------+-----------------+
* - Winner winner chicken dinner
Run Code Online (Sandbox Code Playgroud)

结果如下:

Time Taken (seconds): 11.558017015457

Memory: 963640

SomeClass Object
(
    [aaa] => aaa
    [bbb] => bbb
    [ccc] => aaabbb
)

-----

Time Taken (seconds): 10.872401237488

Memory: 2563136

AnotherClass Object
(
    [aaa] => aaa
    [bbb] => bbb
    [ccc] => aaabbb
)

----

Time Taken (seconds): 59.879059791565

Memory: 905848

SetterClass Object
(
    [aaa] => aaa
    [bbb] => bbb
    [ccc] => aaabbb
)

----

Time Taken (seconds): 60.484427213669

Memory: 905792

SetterClassDefineReturn Object
(
    [aaa] => aaa
    [bbb] => bbb
    [ccc] => aaabbb
)

----

Time Taken (seconds): 62.783381223679

Memory: 745792

SetterClassSetFromParam Object
(
    [aaa] => aaa
    [bbb] => bbb
    [ccc] => aaabbb
)

----

Time Taken (seconds): 72.155715942383

Memory: 745824

SetterClassSetKeyAndParam Object
(
    [aaa] => aaa
    [bbb] => bbb
    [ccc] => aaabbb
)

----

Time Taken (seconds): 11.212271928787

Memory: 2505824

stdClass Object
(
    [aaa] => aaa
    [bbb] => bbb
    [ccc] => aaabbb
)

----

Time Taken (seconds): 9.5637300014496

Memory: 2305848

Array
(
    [aaa] => aaa
    [bbb] => bbb
    [ccc] => aaabbb
)

Run Code Online (Sandbox Code Playgroud)


Qch*_*cho 5

麦哲伦的脚本@ PHP 7.3.5

  • SomeClass Object 是最快和最轻的。
  • Array 1.32 倍速度。2.70 倍内存。
  • stdClass Object 1.65 倍速度。2.94 倍内存。

原始输出:

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
)
Run Code Online (Sandbox Code Playgroud)


Fil*_*erg 1

您始终可以检查 PHP 源代码以获取类似的微性能功能。

但乍一看,不执行 ['value'] 不会更快,因为 PHP 需要对在哪里找到 ['value'] 进行查找,即使哈希表查找应该是 O(1),但这并不能保证。使用文本索引时会产生更多开销。

如果对象只包含 1 个需要访问的变量(即值),则使用对象会产生更多开销。