Penggunaan fungsi NANOSLEEP pada PHP

Saya menyadari yang kedua menghindari overhead panggilan fungsi ( update , sebenarnya merupakan konstruksi bahasa), tetapi akan menarik untuk mengetahui apakah yang satu lebih baik dari yang lain. Saya telah menggunakan unset() untuk sebagian besar pengkodean saya, tetapi saya baru-baru ini melihat beberapa kelas terhormat yang ditemukan di internet yang menggunakan $var = null sebagai gantinya.

Apakah ada yang disukai, dan apa alasannya?

Itu disebutkan di halaman setel manual pada 2009 :

unset() tidak hanya sesuai dengan namanya - hapus variabel. Itu tidak memaksa pembebasan memori segera. Pemulung sampah PHP akan melakukannya ketika cocok - dengan niat segera, karena siklus CPU itu tidak diperlukan, atau selambat-lambatnya sebelum skrip kehabisan memori, apa pun yang terjadi terlebih dahulu.

Jika Anda melakukan $whatever = null; maka Anda menulis ulang data variabel. Anda mungkin mendapatkan memori lebih cepat/menyusut lebih cepat, tetapi mungkin mencuri siklus CPU dari kode yang benar-benar membutuhkannya lebih cepat, menghasilkan waktu eksekusi keseluruhan yang lebih lama.

(Sejak 2013, halaman manual unset jangan sertakan bagian itu lagi)

Perhatikan bahwa hingga php5.3, jika Anda memiliki dua objek dalam referensi melingkar , seperti dalam hubungan orangtua-anak, panggilan tidak disetel () pada objek induk tidak akan membebaskan memori yang digunakan untuk referensi induk pada anak. obyek. (Memori juga tidak akan dibebaskan ketika objek induk dikumpulkan sampah.) ( bug 33595 )


Pertanyaan " perbedaan antara tidak disetel dan = null " merinci beberapa perbedaan:


unset($a) juga menghapus $a dari tabel simbol; sebagai contoh:

$a = str_repeat('hello world ', 100);
unset($a);
var_dump($a);

Output:

Notice: Undefined variable: a in xxx
NULL

Tetapi ketika $a = null digunakan:

$a = str_repeat('hello world ', 100);
$a = null;
var_dump($a);
Outputs:

NULL

Tampaknya $a = null sedikit lebih cepat daripada unset() mitra: memperbarui entri tabel simbol tampaknya lebih cepat daripada menghapusnya.


  • ketika Anda mencoba menggunakan variabel (unset) yang tidak ada, kesalahan akan dipicu dan nilai untuk ekspresi variabel akan menjadi nol. (Karena, apa lagi yang harus PHP lakukan? Setiap ekspresi perlu menghasilkan nilai tertentu.) 
  • Variabel dengan null ditugaskan untuk itu masih merupakan variabel normal.

unset sebenarnya bukan fungsi, tetapi konstruksi bahasa . Ini tidak lebih dari panggilan fungsi daripada return atau include.

Selain masalah kinerja, penggunaan unset membuat kode maksud Anda lebih jelas.

Dengan melakukan unset () pada variabel, Anda pada dasarnya telah menandai variabel untuk 'pengumpulan sampah' (PHP tidak benar-benar memilikinya, tetapi sebagai contohnya) sehingga memori tidak segera tersedia. Variabel tidak lagi menampung data, tetapi tumpukan tetap pada ukuran yang lebih besar. Melakukan metode nol menjatuhkan data dan mengecilkan memori tumpukan segera.

Ini berasal dari pengalaman pribadi dan juga yang lainnya. Lihat komentar dari fungsi unset () di sini .

Saya pribadi menggunakan unset () di antara iterasi dalam satu lingkaran sehingga saya tidak harus memiliki penundaan stack yang ukurannya menjadi yo-yo. Data hilang, tetapi jejak tetap ada. Pada iterasi berikutnya, memori sudah diambil oleh php dan dengan demikian, lebih cepat untuk menginisialisasi variabel berikutnya.


Per itu sepertinya "= null" lebih cepat.

Hasil PHP 5.4:

  • butuh 0,88389301300049 detik
  • butuh 2,1757180690765 detik

Hasil PHP 5.3:

  • butuh 1,7235369682312 detik
  • butuh 2,9490959644318 detik

Hasil PHP 5.2:

  • butuh 3,0069220066071 detik
  • butuh 4,7002630233765 detik

Hasil PHP 5.1:

  • butuh 2,6272349357605 detik
  • butuh waktu 5,0403649806976 detik

Hal-hal mulai terlihat berbeda dengan PHP 5.0 dan 4.4.

5.0:

  • butuh 10,038941144943 detik
  • butuh 7,0874409675598 detik

4.4:

  • butuh 7,5352551937103 detik
  • butuh 6,6245851516724 detik

Ingat microtime (true) tidak berfungsi di PHP 4.4 jadi saya harus menggunakan contoh microtime_float yang diberikan di php.net/microtime/Example # 1.

Itu membuat perbedaan dengan elemen array.

Pertimbangkan contoh ini

$a = array('test' => 1);
$a['test'] = NULL;
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";

Di sini, 'tes' kuncinya masih ada. Namun, dalam contoh ini

$a = array('test' => 1);
unset($a['test']);
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";

kunci tidak ada lagi.

Ia bekerja dengan cara berbeda untuk variabel yang disalin dengan referensi:

$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

Mengenai objek, terutama dalam skenario lazy-load, orang harus mempertimbangkan pengumpul sampah berjalan dalam siklus CPU siaga, jadi anggap Anda akan mendapat masalah ketika banyak objek memuat penalti kecil waktu akan menyelesaikan pembebasan memori.

Gunakan time_nanosleep untuk mengaktifkan GC untuk mengumpulkan memori . Mengatur variabel ke nol diinginkan.

Diuji pada server produksi, awalnya pekerjaan yang dikonsumsi 50MB dan kemudian dihentikan . Setelah nanosleep digunakan 14MB adalah konsumsi memori yang konstan.

Orang seharusnya mengatakan ini tergantung pada perilaku GC yang dapat berubah dari versi PHP ke versi . Tetapi itu berfungsi pada PHP 5.3 baik-baik saja.

misalnya. contoh ini (kode diambil dari VirtueMart2 google feed)

for($n=0; $n" . memory_get_usage() . "";//$ids[$n];
        time_nanosleep(0, 10000000);
    }

    $product = $productModel->getProductSingle((int)$ids[$n],true, true, true);
    ...

Saya masih ragu tentang ini, tetapi saya sudah mencobanya di skrip saya dan saya menggunakan xdebug untuk mengetahui bagaimana itu akan mempengaruhi penggunaan memori aplikasi saya . Skrip ini diatur pada fungsi saya seperti ini:

function gen_table_data($serv, $coorp, $type, $showSql = FALSE, $table = 'ireg_idnts') {
    $sql = "SELECT COUNT(`operator`) `operator` FROM $table WHERE $serv = '$coorp'";
    if($showSql === FALSE) {
        $sql = mysql_query($sql) or die(mysql_error());
        $data = mysql_fetch_array($sql);
        return $data[0];
    } else echo $sql;
}

Dan saya menambahkan unset tepat sebelum kode return dan itu memberi saya: 160200 Kemudian saya mencoba mengubahnya dengan $sql = NULL dan itu memberi saya: 160224 :)

Tetapi ada sesuatu yang unik pada perbandingan ini ketika saya tidak menggunakan unset () atau NULL, xdebug memberi saya 160144 sebagai penggunaan memori

Jadi, saya pikir memberikan baris untuk menggunakan unset () atau NULL akan menambahkan proses ke aplikasi Anda dan akan lebih baik untuk tetap Asal dengan kode Anda dan mengurangi variabel yang Anda gunakan seefektif mungkin.

Perbaiki saya jika saya salah, terima kasih

Saya membuat tes kinerja baru untuk unset dan =null, karena seperti yang disebutkan dalam komentar yang ditulis di sini memiliki kesalahan (menciptakan kembali elemen-elemen). Saya menggunakan array, seperti yang Anda lihat tidak masalah sekarang.

';

$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
    unset($arr2[$i]);
}
$elapsed = microtime(true) - $start;

echo 'took '. $elapsed .'seconds
';

Tetapi saya hanya dapat mengujinya di server PHP 5.5.9, berikut hasilnya: - butuh 4,4571571350098 detik - mengambil 4,4425978660583 detik

Saya lebih suka unset untuk alasan keterbacaan.

Kode unset jika tidak membebaskan memori langsung masih sangat membantu dan akan menjadi praktik yang baik untuk melakukan ini setiap kali kita meneruskan langkah-langkah kode sebelum kita keluar dari suatu metode. perhatikan ini bukan tentang membebaskan memori langsung. Memori segera adalah untuk CPU, bagaimana dengan memori sekunder yaitu RAM.

dan ini juga menangani tentang mencegah kebocoran memori. 

silakan lihat tautan ini http://www.hackingwithphp.com/18/1/11/be-wary-of-garbage-collection-part-2

saya telah menggunakan unset untuk waktu yang lama sekarang.

praktik yang lebih baik seperti ini dalam kode untuk secara instan menghapus semua variabel yang telah digunakan sebagai array. 

$data['tesst']='';
$data['test2']='asdadsa';
....
nth.

dan just unset($data); untuk membebaskan semua penggunaan variabel.

silakan lihat topik terkait untuk tidak disetel

Seberapa pentingkah untuk menghapus variabel di PHP?

[bug]

PHP 7 sudah bekerja pada masalah manajemen memori seperti itu dan penggunaannya dikurangi hingga minimal.


PHP 7.1 Outpu:

mengambil 0,16778993606567 detik mengambil 0,16630101203918 detik

Sebagai catatan, dan tidak termasuk waktu yang diperlukan:

First:
"; $x = str_repeat('x', 80000); echo memory_get_usage() . "
\n"; echo memory_get_peak_usage() . "
\n"; echo "
Unset:
"; unset($x); $x = str_repeat('x', 80000); echo memory_get_usage() . "
\n"; echo memory_get_peak_usage() . "
\n"; echo "
Null:
"; $x=null; $x = str_repeat('x', 80000); echo memory_get_usage() . "
\n"; echo memory_get_peak_usage() . "
\n"; echo "
function:
"; function test() { $x = str_repeat('x', 80000); } echo memory_get_usage() . "
\n"; echo memory_get_peak_usage() . "
\n"; echo "
Reasign:
"; $x = str_repeat('x', 80000); echo memory_get_usage() . "
\n"; echo memory_get_peak_usage() . "
\n";

Ia kembali

First:

Unset:

Null:

function:

Reasign:
438296
520216 <-- double usage.

Kesimpulannya, memori bebas nol dan tidak disetel seperti yang diharapkan (tidak hanya pada akhir eksekusi). Juga, menetapkan ulang suatu variabel memegang nilai dua kali pada beberapa titik (520216 versus 438352)