Saat ini saya mencoba untuk meningkatkan beberapa modul mengenai kinerja.
Beberapa dari Anda mungkin tahu penggunaan walk()
metode pengumpulan yang sangat berguna untuk menghindari perulangan melalui produk secara langsung.
Selain itu dan terima kasih kepada @Vinai, Anda juga dapat menggunakan delete()
metode pengumpulan .
Tapi saya perhatikan bahwa file asli Magento 1 tidak selalu menggunakan metode apa pun untuk dihapus.
Salah satu kode terburuk yang pernah saya lihat adalah massDelete()
metode dari app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
mana produk dimuat dalam satu lingkaran sebelum dihapus .
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')->load($productId);
Mage::dispatchEvent('catalog_controller_product_delete', array('product' => $product));
$product->delete();
}
Jadi saya melakukan beberapa tes kinerja, menambahkan beberapa panggilan logging untuk memeriksa waktu yang dibutuhkan dan penggunaan memori untuk 100 penghapusan produk.
Tes 1: walk
metode
Saya mengganti kode asli yang disisipkan di atas dengan kode ini:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->walk('delete');
Dan hasil saya adalah sebagai berikut pada server dev jelek saya (rata-rata berdasarkan 10 tes):
- Kode asli: 19,97 detik, 15,84 MB digunakan
- Kode khusus: 17.12 detik, 15.45MB digunakan
Jadi untuk penghapusan 100 produk, kode khusus saya adalah 3 detik lebih cepat dan menggunakan 0.4MB lebih sedikit.
Tes 2: Menggunakan delete()
metode pengumpulan
Saya mengganti kode asli dengan yang ini:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->delete();
Dan mind blown di sini adalah hasilnya:
- Kode asli: 19,97 detik, 15,84 MB digunakan
- Kode khusus: 1,24 detik, 6,34MB digunakan
Jadi untuk penghapusan 100 produk, kode khusus saya adalah 18 detik lebih cepat dan menggunakan 9MB lebih sedikit.
Seperti yang dinyatakan dalam komentar, sepertinya metode ini tidak memicu peristiwa Magento (setelah memuat, setelah menghapus) atau indeks / cache flush.
Pertanyaan
Jadi pertanyaan saya adalah: adakah alasan mengapa tim inti Magento tidak menggunakan walk('delete')
atau bahkan lebih baik menggunakan delete()
metode pengumpulan daripada memuat produk dalam satu lingkaran (yang kita semua tahu adalah praktik yang sangat sangat buruk)?
Tujuan utamanya adalah untuk mengetahui poin-poin penting tersebut dalam kasus pengembangan modul: apakah ada kasus tertentu di mana seseorang tidak dapat menggunakan metode walk
/ collection delete()
?
SUNTING: alasannya jelas bukan karena catalog_controller_product_delete
peristiwa yang dikirim karena kode yang sama dapat ditemukan di beberapa tempat (periksa massDelete
metode) di inti Magento. Saya telah menggunakan contoh produk untuk menyoroti kinerja karena biasanya merupakan entitas terbesar
delete()
membuat kueri HAPUS alih-alih memuat koleksi dan menghapus setiap produk. Dengan itu Anda akan benar-benar kehilangan acara.
getSingleton()
sebagai ukuran kinerja, bukan penggunaan koleksi yang jelas. Oh dan itu mungkin untuk memicu acara dengan koleksi juga, hanya saja tidak dengan jalanwalk()
pintas.