IT

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

lottoking 2020. 9. 25. 08:19

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


나는 반복하고 몇 가지 수학을 수행해야하는 신경망을 많은 양의 PHP 수업을 가지고 있습니다. 인스턴스보다 연관 배열을 사용하는 것이 더 나을지 궁금합니다.

주위의 나는 3640object-를 다루고 있으며 그 500위에 (기껏해야)을 time- 반복 하므로 모든 micro-최적화가 큰 도움이됩니다. 불가피 할 빠를 그것은을 구석으로 $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에 대한 개요

  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는 클래스를 사용하는 것과 유사하지만 더 많은 메모리를 사용합니다.

이 코드를 "프로파일 링"(인스턴스 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 기능이 필요하지 않습니다.


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

$object->value백엔드가 배열 일 수 있기 때문에 작동 방식에 대한 코드를 보여주지 않습니다. 이론적으로 배열을 사용하는 것이 함수 호출이 하나 더 적기 때문에 더 빠 사용합니다. 조회를 수행하는 비용은 함수 호출에 비해 아마도 엄청날 것입니다. 변수라면 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는 해시 테이블 조회가 O (1)이어야하는 경우에도 PHP가 [ 'value']를 찾을 수있는 위치를 찾아야하기 때문에 보장되지 않습니다. 텍스트 인덱스를 사용할 때 더 많은 오버 헤드가 있습니다.

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


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
)

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

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

참고 URL : https://stackoverflow.com/questions/2193049/php-objects-vs-arrays-performance-comparison-while-iterating