私は膨大な量のPHPを繰り返し処理し、いくつかの数学を実行しなければならないニューラルネットワークのオブジェクトを持っています。クラス?
私は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の結論
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
)
「プロファイリング」にこのコードを使用しました(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で出力します:
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
したがって、結論:objectsはPHP 5.2でも遅くなります。オブジェクトのoop機能が本当に必要でない限り、オブジェクトを使用しないでください。
私はmagallanesのコードをphp 7.0.9で使用しています:
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
)
$object->value
は、バックエンドが配列である可能性があるため、機能します。この場合、理論的に関数呼び出しが1つ少ないため、配列の使用が高速になります。ルックアップを実行するコストは、おそらく関数呼び出しに比べて莫大です。変数の場合、PHPのオブジェクトと配列は非常によく似た実装を持っているので、違いはほとんどありません。
最適化を検討している場合は、プロファイルを作成して、ほとんどの時間をどこで使用しているかを確認する必要があります。オブジェクトを配列に変更しても大きな違いはないと思います。
これは一種の古い投稿だと思うので、更新するつもりでした。 Zend CE 5.3.21で行われたコードと統計を以下に示します。情報全体をテストし、情報を保存して引き戻そうとしました。
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;
}
}
そのようなマイクロパフォーマンス機能については、PHPソースコードをいつでも確認できます。
しかし、一見したところ、['value']の実行は速くなりません。PHP ['value']がどこにあるかを調べる必要があるからです。 (1)、それは保証されていません。Text-indexを使用すると、オーバーヘッドが増えます。
オブジェクトに、アクセスする必要がある変数が1つしか含まれていない場合、オブジェクトを使用するとオーバーヘッドが増えます。
配列とクラスのパフォーマンスが同じである場合、ビジネスデータの格納/受け渡しに事前定義されたクラスのオブジェクトを使用すると、プログラムのロジックとコードが読みやすくなります。
今日、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.3.5
SomeClass Object
は最速かつ最軽量です。Array
1.32x速度。 2.70xメモリ。stdClass Object
1.65x速度。 2.94xメモリ。生の出力:
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
)