두 번째는 함수 호출의 오버 헤드를 피한다는 것을 알고 있습니다 ( update , 실제로 언어 구성입니다). 하나가 다른 것보다 낫다면 흥미로울 것입니다. 나는 unset()
대부분의 코딩에 사용하고 있지만 최근에는 $var = null
대신에 그물에서 발견되는 존경할만한 몇 가지 클래스를 살펴 보았습니다 .
선호하는 것이 있습니까? 추론은 무엇입니까?
답변
2009 년 설정되지 않은 매뉴얼 페이지에서 언급되었습니다 .
unset()
변수 이름을 설정합니다. 메모리를 즉시 해제하지 않습니다. PHP의 가비지 콜렉터는 CPU 사이클이 필요하지 않거나 스크립트가 메모리 부족으로 늦어지기 전에 늦게까지 의도적으로 적합 할 때이를 수행합니다.당신이하고 있다면
$whatever = null;
변수의 데이터를 다시 쓰고 있습니다. 메모리를 더 빨리 확보 / 축소 할 수 있지만 실제로 필요한 코드에서 CPU주기를 훔쳐서 전체 실행 시간이 길어질 수 있습니다.
(2013 년 이후로 해당 unset
매뉴얼 페이지 에는 해당 섹션이 더 이상 포함되지 않습니다)
php5.3까지 부모-자식 관계와 같이 순환 참조에 두 개의 객체가있는 경우 부모 객체에서 unset ()을 호출하면 자식 객체의 부모 참조에 사용 된 메모리가 해제되지 않습니다. (부모 객체가 가비지 수집 될 때 메모리가 해제되지 않습니다.) ( 버그 33595 )
” unset과 = null의 차이점 “이라는 질문에는 몇 가지 차이점이 자세히 설명되어 있습니다.
unset($a)
$a
기호 테이블에서 제거 합니다. 예를 들면 다음과 같습니다.
$a = str_repeat('hello world ', 100);
unset($a);
var_dump($a);
출력 :
Notice: Undefined variable: a in xxx
NULL
그러나 언제
$a = null
사용됩니까?
$a = str_repeat('hello world ', 100);
$a = null;
var_dump($a);
Outputs:
NULL
그 보인다
$a = null
조금 더 빨리 그보다unset()
기호 테이블 항목을 업데이트하면 빨리 제거보다 나타납니다 : 대응.
- 존재하지 않는 (
unset
) 변수 를 사용하려고 하면 오류가 발생하고 변수 표현식의 값이 널이됩니다. (PHP는 다른 무엇을해야합니까? 모든 표현식은 어느 정도 가치가 있어야합니다.) - null이 할당 된 변수는 여전히 완벽하게 정상적인 변수입니다.
답변
unset
실제로 함수는 아니지만 언어 구문 입니다. 더 이상 a return
또는 a보다 함수 호출이 아닙니다 include
.
성능 문제 외에도 unset
코드를 사용 하면 코드의 의도가 훨씬 명확 해집니다.
답변
변수에 대해 unset ()을 수행하면 본질적으로 변수를 ‘가비지 수집'(PHP에는 실제로는 없지만 예를 들어)으로 표시하므로 메모리를 즉시 사용할 수 없습니다. 변수는 더 이상 데이터를 저장하지 않지만 스택은 더 큰 크기로 유지됩니다. null 메서드를 수행하면 데이터가 삭제되고 스택 메모리가 거의 즉시 축소됩니다.
이것은 개인적인 경험과 다른 사람들로부터 온 것입니다. unset () 함수의 주석은 here을 참조하십시오 .
개인적으로 루프에서 반복 사이에 unset ()을 사용하므로 스택 크기가 지연 될 필요가 없습니다. 데이터는 사라졌지 만 설치 공간은 남아 있습니다. 다음 반복에서 메모리는 이미 PHP에 의해 취해지고 있으므로 다음 변수를 더 빨리 초기화합니다.
답변
<?php
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
$a = NULL;
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
unset($a);
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
?>
“= null”이 더 빠를 것 같습니다.
PHP 5.4 결과 :
- 0.88389301300049 초 소요
- 2.1757180690765 초가 걸렸습니다.
PHP 5.3 결과 :
- 1.7235369682312 초가 걸렸습니다.
- 2.9490959644318 초 걸렸다
PHP 5.2 결과 :
- 3.0069220066071 초 걸렸다
- 4.7002630233765 초가 걸렸습니다.
PHP 5.1 결과 :
- 2.6272349357605 초 걸렸다
- 5.0403649806976 초가 걸렸다
PHP 5.0과 4.4에서는 상황이 다르게 보이기 시작합니다.
5.0 :
- 10.038941144943 초 걸렸다
- 7.0874409675598 초 소요
4.4 :
- 소요 7.5352551937103 초
- 6.6245851516724 초가 걸렸습니다.
microtime (true)은 PHP 4.4에서 작동하지 않으므로 php.net/microtime / Example # 1에 제공된 microtime_float 예제를 사용해야했습니다.
답변
배열 요소와 차이를 만듭니다.
이 예를 고려하십시오
$a = array('test' => 1);
$a['test'] = NULL;
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";
여기에는 키 ‘테스트’가 여전히 존재합니다. 그러나이 예에서는
$a = array('test' => 1);
unset($a['test']);
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";
키가 더 이상 존재하지 않습니다.
답변
참조로 복사 된 변수에 대해 다른 방식으로 작동합니다.
$a = 5;
$b = &$a;
unset($b); // just say $b should not point to any variable
print $a; // 5
$a = 5;
$b = &$a;
$b = null; // rewrites value of $b (and $a)
print $a; // nothing, because $a = null
답변
객체, 특히 지연로드 시나리오에서 가비지 콜렉터가 유휴 CPU 주기로 실행 중임을 고려해야하므로 많은 오브젝트가 작은 시간 페널티를로드 할 때 문제가 발생한다고 가정하면 메모리 확보가 해결됩니다.
GC가 메모리를 수집 할 수있게하려면 time_nanosleep을 사용하십시오. 변수를 null로 설정하는 것이 바람직합니다.
프로덕션 서버에서 테스트 한 결과 원래 작업이 50MB를 소비 한 후 중지되었습니다. nanosleep을 사용한 후 14MB는 일정한 메모리 소비였습니다.
PHP 버전에서 버전으로 변경 될 수있는 GC 동작에 따라 달라집니다. 그러나 그것은 PHP 5.3에서 잘 작동합니다.
예. 이 샘플 (VirtueMart2 Google 피드에서 가져온 코드)
for($n=0; $n<count($ids); $n++)
{
//unset($product); //usefull for arrays
$product = null
if( $n % 50 == 0 )
{
// let GC do the memory job
//echo "<mem>" . memory_get_usage() . "</mem>";//$ids[$n];
time_nanosleep(0, 10000000);
}
$product = $productModel->getProductSingle((int)$ids[$n],true, true, true);
...