PHP 배열 대 배열 — 반복하는 동안 성능 비교
나는 반복하고 몇 가지 수학을 수행해야하는 신경망을 많은 양의 PHP 수업을 가지고 있습니다. 인스턴스보다 연관 배열을 사용하는 것이 더 나을지 궁금합니다.
주위의 나는 3640
object-를 다루고 있으며 그 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에 대한 개요
- 클래스는 배열보다 빠 사용 (하지만 약간).
- stdClass는 악합니다.
- 클래스는 배열보다 약간 메모리를 사용합니다. (약 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에 대한 개요
- 배열의 경우 PHP 5.5가 PHP 5.4보다 빠르며 객체의 경우 거의 동일합니다.
- 클래스는 PHP 5.5와 배열의 최적화 덕분에 배열보다 느립니다.
- stdClass는 악합니다.
- 클래스는 배열보다 약간의 메모리를 사용합니다. (약 30-40 % 감소 !!).
- 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
...
}
'IT' 카테고리의 다른 글
위치 : 절대 및 부모 높이? (0) | 2020.09.25 |
---|---|
다중 사례 환경에서 HttpClient를 사용하는 모범 사례 (0) | 2020.09.25 |
Azure 리소스 그룹의 이름을 어떻게 변경하나요? (0) | 2020.09.25 |
Google App Engine Java의 RESTful 애플리케이션? (0) | 2020.09.25 |
헤더 내부 앵커 또는 그 반대 -SEO와 관련하여 다른 점이? (0) | 2020.09.25 |