PHP 객체 대 배열 — 반복하는 동안 성능 비교


92

나는 반복하고 몇 가지 수학을 수행해야하는 신경망을위한 엄청난 양의 PHP 객체를 가지고 있습니다. 클래스 인스턴스보다 연관 배열을 사용하는 것이 더 나을지 궁금합니다.

나는 주변의 3640객체를 다루고 있으며 그 500위에 (기껏해야) 시간을 반복 하므로 모든 미세 최적화가 큰 도움이됩니다. 그것은 불가피 할 빠를 것 $object['value']보다 $object->value?

편집 : 그래서 둘 다 동일합니다. 하지만 생성자에 약간의 오버 헤드가있을 것 같습니까? 어느 쪽이든 내 아름다운 수업을 더러운 배열로 바꾸고 싶지 않다고 생각합니다 : P

답변:


65

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에 대한 결론

  1. 클래스는 배열보다 빠릅니다 (하지만 약간).
  2. stdClass는 악합니다.
  3. 클래스는 배열보다 적은 메모리를 사용합니다. (약 30 ~ 40 % 할인 !!)

추신 : 참고로 클래스가 정의되었지만 멤버가 정의되어 있으면이 클래스의 사용이 느립니다. 또한 더 많은 메모리를 사용합니다. 분명히 비밀은 멤버를 정의하는 것입니다.

최신 정보

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에 대한 결론

  1. 배열의 경우 PHP 5.5가 PHP 5.4보다 빠르며 객체의 경우 거의 동일합니다.
  2. 클래스는 PHP 5.5와 배열의 최적화 덕분에 배열보다 느립니다.
  3. stdClass는 악합니다.
  4. 클래스는 여전히 배열보다 적은 메모리를 사용합니다. (약 30-40 % 감소 !!).
  5. SplFixedArray는 Class를 사용하는 것과 비슷하지만 더 많은 메모리를 사용합니다.

잘하셨습니다. 이를 중첩 배열 등으로 확장하는 것이 흥미로울 것입니다. 다른 PHP 성능에 대한 흥미로운 사이트 : phpbench.com php-benchmark-script.com 하지만 메모리도 사용하는 것이 좋습니다.
Heath N

2
PHP7에서는 배열과 객체의 차이가 더욱 커졌습니다. 스크립트는 런타임 30 %와 메모리 60 %의 차이를 보여줍니다. 그것은 내 컴퓨터 일 뿐이지 만 경험 상으로는 배열을 구조체로 사용하지 마십시오. 대신 개체 사용 :)
KingCrunch

이 경우 객체가 클래스와 다른가요?
Matt G

PHP7 업데이트를 희망하여 이것을 북마크하십시오. 그리고 해당되는 경우 곧 출시 될 PHP8 일 것입니다. @magallanes
s3c

8

이 코드를 "프로파일 링"(인스턴스 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

결론적으로 : 객체는 PHP 5.2에서도 느립니다. oop 기능이 실제로 필요하지 않으면 개체를 사용하지 마십시오.


7
사용자 levans stackoverflow.com/users/1473035/levans에서 : 나는 이것을 5.3.8로 실행했고 객체는 더 느 렸고 배열의 경우 0.51839280128479, 객체의 경우 0.85355806350708이었습니다. 나는 또한 5.4.13에서 실행했고 반대 결과를 얻었는데, 아마도 5.4에서 수행 된 클래스 최적화, 배열의 경우 0.6256799697876 대 0.43650078773499 때문일 것입니다. 따라서 테이블이 바뀌고 이제 물건이 갈 길인 것처럼 보입니다.
Jean-Bernard Pellerin 2013

1
좋은 대답입니다. 방금 XAMPP (Apache)에서 테스트 한 결과 아래와 같은 결과를 얻었습니다. arrays : 0.5174868106842 Array ([aaa] => aaa [bbb] => bbb [ccc] => aaabbb) obj : 0.72189617156982 stdClass Object ([aaa] => aaa [bbb] => bbb [ccc] => aaabbb) phpversion 5.4.19
ilhnctn

1
나는 또한 5.4.13에서 실행했지만 Jean-Bernard Pellerin : Arrays : 0.5020840167999 Objects : 1.0378720760345 그래서 아직 객체에 커밋하지 않았습니다.
simontemplar

나는 코드를 약간 변경했고 Class는 php 5.4 (5.4.16 32bits Windows)의 Arrays보다 빠릅니다. 이유를 설명하는 새로운 답변을 넣었습니다.
magallanes 2014-06-02

PHP 5.5.11 결과 : 배열 : 0.17430은 개체 : 0.24183
렉스

3

나는 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
)                      

1
그리고 stdClass는 실제 문자열 숫자 키를 사용할 수 있다는 것을 잊지 마십시오. [ '1'=> 1]은 [1 => 1]로 저장되지만 $a=new stdClass(); $a->{1} = 1; $b=(array)$a;get real [ '1'=> 1]을 사용할 수 있습니다 .
chariothy

2
결론적으로 .. 어레이는 18 % 더 빠르지 만 2.7 배 더 많은 메모리를 소비합니다.
jchook

3

magallanes의 스크립트 @ PHP 7.3.5

  • SomeClass Object 가장 빠르고 가볍습니다.
  • Array 1.32 배속. 2.70x 메모리.
  • stdClass Object 1.65 배속. 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
)

3

이 질문에 여전히 관심이있는 사람을 위해 :) 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
)

결론

배열은 클래스 객체보다 4 (!) 메모리를 사용합니다.
클래스 객체가 약간 더 빠릅니다.
stdClass 여전히 악 © magallanes :)


2

$object->value백엔드가 이론적으로 배열 일 수 있으므로 작동 방식에 대한 코드를 보여주지 않았습니다. 으로 배열을 사용하는 것이 함수 호출이 하나 적기 때문에 더 빠를 것입니다. 조회를 수행하는 데 드는 비용은 함수 호출에 비해 엄청날 것입니다. 변수라면 PHP의 객체와 배열이 매우 유사한 구현을 갖기 때문에 차이가 거의 없습니다.

최적화를보고있는 경우 대부분의 시간이 사용되는 위치를 확인하기 위해 프로파일 링해야합니다. 객체를 배열로 변경해도 큰 차이가 없다고 생각합니다.


나는 값이 공개 변수라고 가정 했으므로 해시 조회는 그렇지 않을 수 있지만 방어 적으로 O (1)입니다.
Filip Ekberg

2

나는 이것이 일종의 오래된 게시물이라는 것을 알았으므로 업데이트 할 것이라고 생각했습니다. 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;
  }
}

2

오늘 @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

아래는 수정 된 스크립트입니다. 메서드와 정의 형식으로 속성 설정을 테스트하고 싶었습니다. setter 메서드를 사용하면 코드에 큰 타격을 입힌다는 사실에 매우 놀랐습니다. 이제 이것은 많은 앱이이를 달성하지 못하는 매우 구체적인 성능 테스트라는 점을 인정합니다. 그러나 1000 개의 객체와 함께 사용되는 1000 개의 클래스로 초당 1000 개 / 요구 사항을 처리하는 사이트가있는 경우 이것이 성능에 어떤 영향을 미칠 수 있는지 알 수 있습니다.

<?php

set_time_limit(500);

class SomeClass {
    public $aaa;
    public $bbb;
    public $ccc;
}
    
class AnotherClass {
}

class SetterClass {
    public $aaa;
    public $bbb;
    public $ccc;

    public function setAAA() {
        $this->aaa = 'aaa';
    }

    public function setBBB() {
        $this->bbb = 'bbb';
    }

    public function setCCC() {
        $this->ccc = $this->aaa.$this->bbb;
    }
}

class SetterClassDefineReturn {
    public $aaa;
    public $bbb;
    public $ccc;

    public function setAAA():void {
        $this->aaa = 'aaa';
    }

    public function setBBB():void {
        $this->bbb = 'bbb';
    }

    public function setCCC():void {
        $this->ccc = $this->aaa.$this->bbb;
    }
}

class SetterClassSetFromParam {
    public $aaa;
    public $bbb;
    public $ccc;

    public function setAAA(string $val): void {
        $this->aaa = $val;
    }

    public function setBBB(string $val): void {
        $this->bbb = $val;
    }

    public function setCCC(string $val): void {
        $this->ccc = $val;
    }
}

class SetterClassSetKeyAndParam {
    public $aaa;
    public $bbb;
    public $ccc;

    public function set(string $key, string $val): void {
        $this->{$key} = $val;
    }
}

function p($i) {
  echo '<pre>';
  print_r($i);
  echo '</pre>';
  echo '<hr>';
}

$t0 = microtime(true);
$arraysOf=[];
$inicio=memory_get_usage(); 
for ($i=0; $i<5000; $i++) {
    $z = new SomeClass();
    for ($j=0; $j<5000; $j++) {
        $z->aaa = 'aaa';
        $z->bbb = 'bbb';
        $z->ccc = $z->aaa.$z->bbb;          
    }
    $arraysOf[]=$z;
}
$fin=memory_get_usage();    
echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>';
echo '<p>Memory: '.($fin-$inicio).'</p>';
p($z);

$t0 = microtime(true);
$arraysOf=[];
$inicio=memory_get_usage(); 
for ($i=0; $i<5000; $i++) {
    $z = new AnotherClass();
    for ($j=0; $j<5000; $j++) {
        $z->aaa = 'aaa';
        $z->bbb = 'bbb';
        $z->ccc = $z->aaa.$z->bbb;          
    }
    $arraysOf[]=$z;
}
$fin=memory_get_usage();    
echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>';
echo '<p>Memory: '.($fin-$inicio).'</p>';
p($z);

$t0 = microtime(true);
$arraysOf=[];
$inicio=memory_get_usage(); 
for ($i=0; $i<5000; $i++) {
    $z = new SetterClass();
    for ($j=0; $j<5000; $j++) {
        $z->setAAA();
        $z->setBBB();
        $z->setCCC();          
    }
    $arraysOf[]=$z;
}
$fin=memory_get_usage();    
echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>';
echo '<p>Memory: '.($fin-$inicio).'</p>';
p($z);

$t0 = microtime(true);
$arraysOf=[];
$inicio=memory_get_usage(); 
for ($i=0; $i<5000; $i++) {
    $z = new SetterClassDefineReturn();
    for ($j=0; $j<5000; $j++) {
        $z->setAAA();
        $z->setBBB();
        $z->setCCC();          
    }
    $arraysOf[]=$z;
}
$fin=memory_get_usage();    
echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>';
echo '<p>Memory: '.($fin-$inicio).'</p>';
p($z);

$t0 = microtime(true);
$arraysOf=[];
$inicio=memory_get_usage(); 
for ($i=0; $i<5000; $i++) {
    $z = new SetterClassSetFromParam();
    for ($j=0; $j<5000; $j++) {
        $z->setAAA('aaa');
        $z->setBBB('bbb');
        $z->setCCC('aaabbb');          
    }
    $arraysOf[]=$z;
}
$fin=memory_get_usage();    
echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>';
echo '<p>Memory: '.($fin-$inicio).'</p>';

p($z);

$t0 = microtime(true);
$arraysOf=[];
$inicio=memory_get_usage(); 
for ($i=0; $i<5000; $i++) {
    $z = new SetterClassSetKeyAndParam();
    for ($j=0; $j<5000; $j++) {
        $z->set('aaa', 'aaa');
        $z->set('bbb', 'bbb');  
        $z->set('ccc', 'aaabbb');        
    }
    $arraysOf[]=$z;
}
$fin=memory_get_usage();    
echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>';
echo '<p>Memory: '.($fin-$inicio).'</p>';
p($z);

$t0 = microtime(true);
$arraysOf=[];
$inicio=memory_get_usage(); 
for ($i=0; $i<5000; $i++) {
    $z = new stdClass();
    for ($j=0; $j<5000; $j++) {
        $z->aaa = 'aaa';
        $z->bbb = 'bbb';
        $z->ccc = $z->aaa.$z->bbb;          
    }
    $arraysOf[]=$z;
}
$fin=memory_get_usage();    
echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>';
echo '<p>Memory: '.($fin-$inicio).'</p>';
p($z); 


$t0 = microtime(true);
$arraysOf=[];
$inicio=memory_get_usage(); 
for ($i=0; $i<5000; $i++) {
    $z = [];
    for ($j=0; $j<5000; $j++) {
        $z['aaa'] = 'aaa';
        $z['bbb'] = 'bbb';
        $z['ccc'] = $z['aaa'].$z['bbb'];            
    }
    $arraysOf[]=$z;
}
$fin=memory_get_usage();    
echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>';
echo '<p>Memory: '.($fin-$inicio).'</p>';
p($z);

결과는 다음과 같습니다.

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
)


1

이와 같은 마이크로 성능 기능에 대한 PHP 소스 코드를 언제든지 확인할 수 있습니다.

그러나 언뜻보기에 [ 'value']를 수행하는 것이 더 빠르지는 않을 것입니다. PHP는 해시 테이블 조회가 O (1)이어야하는 경우에도 PHP가 [ 'value']를 찾을 수있는 위치를 찾아야하기 때문에 보장되지 않습니다. 텍스트 인덱스를 사용할 때 더 많은 오버 헤드가 있습니다.

객체에 액세스해야하는 값이 1 개만 포함 된 경우 객체를 사용하는 데 더 많은 오버 헤드가 발생합니다.


그리고 속성이 어디에서 조회 될 것이라고 생각하십니까? 그것들도 해시 테이블에 있습니다 ... (트렁크에서는 다소 사실이지만).
Artefacto

0

배열과 클래스가 동일한 성능이면 비즈니스 데이터를 저장 / 전달하기 위해 미리 정의 된 클래스의 개체를 사용하면 프로그램의 논리와 코드가 더 읽기 쉬워 진다고 생각합니다.

오늘날 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
    ...
}

이것은 다른 입증 된 답변과 모순되며 증거가 없습니다. 그래서 이것은 실제적인 대답 이라기보다 이념적 신념에 가깝습니다.
스콘

0

공정하게 말하면 어떤 종류의 데이터를 가지고 있는지에 달려 있습니다. 다른 답변의 결과는 (다소 또는 적음) * 정확합니다. 명확성을 위해 하단에 테스트 코드를 붙여 넣겠습니다.

여기서 중요한 것은 미리 정의 된 개체를 사용하면 상당한 양의 메모리를 절약 할 수 있다는 것입니다. 절충점은 정확한 구조를 정의해야한다는 사실입니다.

다음 테스트 결과를 고려하십시오.

static obj: 0.04223108291626
memory: 164920
object(staticSet)#1 (3) {
  ["aaa"]=>
  string(3) "aaa"
  ["bbb"]=>
  string(3) "bbb"
  ["ccc"]=>
  string(6) "aaabbb"
}
---------------------------------------
static obj with an additional prop: 0.042968988418579
memory: 524920
object(staticSet2)#1000 (3) {
  ["aaa"]=>
  string(3) "aaa"
  ["bbb"]=>
  string(3) "bbb"
  ["ddd"]=>
  string(6) "aaabbb"
}
---------------------------------------

내가 틀렸을 수도 있지만 PHP 소스를 조사하지는 않았지만 PHP에 관한 한 모든 것이 배열이라고 믿습니다. 미리 정의 된 개체는 잘 정의 된 배열 일뿐입니다. 흥미로운 점은 값 유형이 효과가 없다는 것입니다. 문자열 값 '1'은 bool 값 true와 같은 양의 메모리를 차지합니다.

왜? PHP가 배열이기 때문에 setter 함수가있는 객체가 있다면 PHP가하는 일이 있습니다.

$objects = ['objectName' => [
    'aaa' => '',
    'bbb' => '',
    'ccc' => '',
    'setValue:f' => function('name', 'value') { ... }
    ]
];

실행할 때마다 소품 이름을 검색하는 기능 키와 배경에서 소품 유형 등에 대한 유효성 검사를 수행합니다. 미리 정의 된 객체의 메모리 절약은 메모리 청크를 할당하는 대신 설정된 길이 (PHP에서는 불가능)의 배열을 정의하는 데서 비롯됩니다.

결론:

정적 개체 : 예 ! 우리는 메모리를 절약합니다! 그러나 정의 외부에 추가하려고하면 stdClass보다 커집니다.

['aaa'] into [['aaa'],['bbb']]

배열 : PHP로 작성한다면 문자열도 PHP의 문자 배열입니다.

사물: 객체는 멋진 기능을 가지고 있으며 코드를 정리하고, 깔끔하고, 모듈화 할 수있는 훌륭한 방법입니다. 그러나 우리 모두 "큰 힘으로 ..."라는 것을 알고 있습니다.

마지막으로 내 테스트 코드와 '*'. 사람들은 스크립트가 실행되는 동안 변수를 정리하지 않으면 메모리에 남아 있지만 실행 시간 (많은)에 영향을 미치지 않으면 메모리 측정에 영향을 미친다는 사실을 잊은 것 같습니다. 따라서 메모리 프로파일 링을 실행하는 동안 unset ()은 친구입니다.

<?php

error_reporting(E_ALL);
ini_set('display_errors',1);

$noOfObjects = 1000;
$noOfOperations = 1000;

class set {
    public function setKey($key, $value) {
        $this->{$key} = $value;
    }
    public function readKey($name) {
        return $this->{$name};
    }
}

class staticSet {
    public string $aaa;
    public string $bbb;
    public string $ccc;
}

class staticSet2 {
    public string $aaa;
    public string $bbb;
}

class staticSet3 {
    public bool $aaa;
    public bool $bbb;
    public bool $ccc;
}

$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage(); 
for ($i=0; $i<$noOfObjects; $i++) {
    $z = array(); // definition
    for ($j=0; $j<$noOfOperations; $j++) {
        $z['aaa'] = 'aaa';
        $z['bbb'] = 'bbb';
        $z['ccc'] = $z['aaa'].$z['bbb'];
    }
    $arraysOf[]=$z;
}
$end=memory_get_usage();  
echo 'arrays: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage(); 
for ($i=0; $i<$noOfObjects; $i++) {
    $z = new set(); // definition
    for ($j=0; $j<$noOfOperations; $j++) {
        $z->setKey('aaa','aaa');
        $z->setKey('bbb','bbb');
        $z->setKey('ccc',$z->readKey('aaa').$z->readKey('bbb'));
    }
    $arraysOf[]=$z;
}
$end=memory_get_usage();  
echo 'dynamic obj: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage(); 
for ($i=0; $i<$noOfObjects; $i++) {
    $z = new staticSet(); // definition
    for ($j=0; $j<$noOfOperations; $j++) {
        $z->{'aaa'} = 'aaa';
        $z->{'bbb'} = 'bbb';
        $z->{'ccc'} = $z->{'aaa'}.$z->{'bbb'};
    }
    $arraysOf[]=$z;
}
$end=memory_get_usage();  
echo 'static obj: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage(); 
for ($i=0; $i<$noOfObjects; $i++) {
    $z = new staticSet2(); // definition
    for ($j=0; $j<$noOfOperations; $j++) {
        $z->{'aaa'} = 'aaa';
        $z->{'bbb'} = 'bbb';
        $z->{'ddd'} = $z->{'aaa'}.$z->{'bbb'};
    }
    $arraysOf[]=$z;
}
$end=memory_get_usage();  
echo 'static obj with an additional prop: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime($noOfObjects);
$start=memory_get_usage(); 
for ($i=0; $i<$noOfObjects; $i++) {
    $z = new Ds\Map(); // definition
    for ($j=0; $j<$noOfOperations; $j++) {
        $z->put('aaa','aaa');
        $z->put('bbb','bbb');
        $z->put('ccc',$z->get('aaa').$z->get('bbb'));
    }
    $arraysOf[]=$z;
}
$end=memory_get_usage();  
echo 'Ds\Map: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage(); 
for ($i=0; $i<$noOfObjects; $i++) {
    $z = new staticSet(); // definition
    for ($j=0; $j<$noOfOperations; $j++) {
        $z->{'aaa'} = '1';
        $z->{'bbb'} = '1';
        $z->{'ccc'} = ($z->{'aaa'} && $z->{'bbb'});
    }
    $arraysOf[]=$z;
}
$end=memory_get_usage();  
echo 'static obj with bool values: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage(); 
for ($i=0; $i<$noOfObjects; $i++) {
    $z = new staticSet3(); // definition
    for ($j=0; $j<$noOfOperations; $j++) {
        $z->{'aaa'} = '1';
        $z->{'bbb'} = '1';
        $z->{'ccc'} = ($z->{'aaa'} && $z->{'bbb'});
    }
    $arraysOf[]=$z;
}
$end=memory_get_usage();  
echo 'static obj with defined bool values: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage(); 
for ($i=0; $i<$noOfObjects; $i++) {
    $z = array('aaa' => '','bbb' => '','ccc' => ''); // definition
    for ($j=0; $j<$noOfOperations; $j++) {
        $z['aaa'] = 'aaa';
        $z['bbb'] = 'bbb';
        $z['ccc'] = $z['aaa'].$z['bbb'];
    }
    $arraysOf[]=$z;
}
$end=memory_get_usage();  
echo 'predefined array: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;


echo 'phpversion '.phpversion().PHP_EOL;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.