Разница между unset и = null
Из случайный пост php.net:
Если вы делаете $whatever = null; то вы переписываете переменную данные. Вы могли бы освободить память/сократить быстрее, но она может украсть CPU циклов из кода, который действительно нуждается в них раньше, в результате чего более длительное время выполнения.
По-видимому, это бесспорная истина поэтому, возможно, кто-то будет так любезен объяснить.
Я имею в виду, что, unset
магически не выполняет какие-либо команды сборки, тогда как $whatever = null;
делает? Ответ, как указано, примерно так же полезен, как сказать
$any = null сбрасывает буфер и кеш L1, тогда как unset очищает буфер и сбрасывает кеш L2.
Техно mumbo jumbo не является ответом.
Ответы
Ответ 1
Важным отличием обоих методов является то, что 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);
Выходы:
NULL
Я также запускал код с помощью теста и обнаружил, что $a = null
примерно на 6% быстрее, чем его аналог unset()
. Кажется, что обновление записи таблицы символов происходит быстрее, чем удаление.
Добавление
Другим отличием (как видно из этого небольшого script), является то, сколько памяти восстанавливается после каждого вызова:
echo memory_get_usage(), PHP_EOL;
$a = str_repeat('hello world ', 100);
echo memory_get_usage(), PHP_EOL;
// EITHER unset($a); OR $a = null;
echo memory_get_usage(), PHP_EOL;
При использовании unset()
возвращаются все, кроме 64 байт памяти, тогда как $a = null;
освобождает все, кроме 272 байта памяти. У меня недостаточно знаний, чтобы знать, почему существует разница в 208 байтов между обоими методами, но это тем не менее.
Ответ 2
При использовании unset использование памяти и время обработки меньше.
http://php.net/manual/en/function.unset.php#105980
Ответ 3
Я сделал простой тест.
Учитывая простой класс:
class Cat{
public $eyes = 2;
public $claws = 4;
public $name = "Kitty";
public $sound = ['Meow', 'Miaou'];
}
Я запускаю этот код
$start = microtime(true);
for($i = 10000000; $i > 0; --$i){
$cat = new Cat;
$cat = null;
}
$end = microtime(true);
printf("Run in %s and use %s memory",
round($end - $start, 2), round(memory_get_usage() / 1000, 2));
Запуск в 1.95 и использование 233.29 памяти
И этот
for($i = 10000000; $i > 0; --$i){
$cat = new Cat;
unset($cat);
}
Запуск в 2.28 и использование 233.1 памяти
Для чего кажется, что метод null
работает быстрее.
Ответ 4
Приведенные выше ответы великолепны, особенно комментарий: "Важное различие между обоими методами заключается в том, что unset ($ a) также удаляет $ a из таблицы символов".
Тем не менее, я не думаю, что кто-то действительно полностью ответил на вопрос в практическом смысле, потому что они не описывают, как они используются. Хорошо, я думаю, мы знаем, что они в основном делают одно и то же. Зачем использовать один над другим?
ноль
Немедленно восстанавливает память (за счет увеличения времени), несмотря на то, что PHP самостоятельно управляет памятью/сборкой мусора.
снята с охраны()
Обычно рекомендуется, так как он восстанавливает память "когда я смогу к ней добраться" и поэтому считается более быстрым, так как не выделяет ему ресурсы сразу.
Когда следует использовать null против unset?
Базовые массивы данных (небольших данных) и т.д. Являются хорошими кандидатами для сброса, поскольку память не станет проблемой. Большие наборы данных и/или где-либо необходимость немедленного восстановления памяти лучше для нуля. Например, такие большие запросы к базе данных могут очень быстро уничтожить ваш потолок памяти PHP, если он вызывается несколько раз в функции и т.д., Что приведет к ошибкам страницы 500 из-за переполнения памяти и т.д. Поэтому, если важна скорость (или вообще, следует предпочитать unset).) и когда мало заботы о наращивании памяти.
Пример: Взятие большого массива и помещение его в MemCache:
list($inv1, $inv2, $inv3, $inv4) = array_chunk($inventory_array),
ceil(count($val['inventory']) / 4));
MemCache::set($cacheKeyInv1, $inv1, $expiry);
MemCache::set($cacheKeyInv2, $inv2, $expiry);
MemCache::set($cacheKeyInv3, $inv3, $expiry);
MemCache::set($cacheKeyInv4, $inv4, $expiry);
for ($i = 1; $i < 5; $i++) {
${"inv" . $i} = null; // why not use unset ?
}
Цикл for очищает данные, можно использовать null или unset, но, поскольку это большой набор данных, возможно, null предпочтительнее, поскольку он быстрее восстанавливает память.
Ответ 5
Используя код
$a = str_repeat('hello world ', 10000);
$start1 = microtime(true);
unset($a);
$stop1 = microtime(true);
$a = str_repeat('hello world ', 10000);
$start2 = microtime(true);
$a = null;
$stop2 = microtime(true);
echo 'unset time lap of '. ( $stop1 - $start1 ) .'<br>';
echo 'null time lap of '. ( $stop2 - $start2 ) .'<br>';
в течение 10 раз:
unset time lap of 5.0067901611328E-6
null time lap of 1.1920928955078E-6
unset time lap of 9.5367431640625E-7
null time lap of 9.5367431640625E-7
unset time lap of 0
null time lap of 9.5367431640625E-7
unset time lap of 2.1457672119141E-6
null time lap of 1.1920928955078E-6
unset time lap of 2.1457672119141E-6
null time lap of 0
unset time lap of 9.5367431640625E-7
null time lap of 0
unset time lap of 1.9073486328125E-6
null time lap of 9.5367431640625E-7
unset time lap of 9.5367431640625E-7
null time lap of 0
unset time lap of 1.9073486328125E-6
null time lap of 9.5367431640625E-7
unset time lap of 0
null time lap of 0
Похоже, что нулевое присвоение имеет меньшее время обработки.