Actualmente estoy tratando de mejorar un par de módulos con respecto al rendimiento.
Algunos de ustedes pueden conocer el uso del walk()
método en la colección, que es muy útil para evitar pasar directamente por los productos.
Además de eso y gracias a @Vinai, también se puede utilizar el delete()
método de recopilación .
Pero noté que los archivos nativos de Magento 1 no siempre usan ninguno de esos métodos para la eliminación.
Uno de los peores códigos que he visto es el massDelete()
método desde app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
donde los productos se cargan en un bucle antes de la eliminación .
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')->load($productId);
Mage::dispatchEvent('catalog_controller_product_delete', array('product' => $product));
$product->delete();
}
Así que realicé algunas pruebas de rendimiento, agregué algunas llamadas de registro para verificar el tiempo necesario y el uso de memoria para la eliminación de 100 productos.
Prueba 1: walk
método
Reemplacé el código original pegado anteriormente con este código:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->walk('delete');
Y mis resultados son los siguientes en mi servidor de desarrollo de mierda (promedio basado en 10 pruebas):
- Código original: 19,97 segundos, 15,84 MB utilizados
- Código personalizado: 17,12 segundos, 15,45 MB utilizados
Entonces, para la eliminación de 100 productos, mi código personalizado es 3 segundos más rápido y usa 0.4MB menos.
Prueba 2: uso del delete()
método de recolección
Reemplacé el código original con este:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->delete();
Y alucinante aquí están los resultados:
- Código original: 19,97 segundos, 15,84 MB utilizados
- Código personalizado: 1,24 segundos, 6,34 MB utilizados
Entonces, para la eliminación de 100 productos, mi código personalizado es 18 segundos más rápido y usa 9 MB menos.
Como se indicó en los comentarios, parece que este método no activa los eventos de Magento (después de la carga, después de eliminar) ni el vaciado del índice / caché.
Pregunta
Entonces mi pregunta es: ¿hay alguna razón por la cual el equipo central de Magento no utilizó el walk('delete')
evento o mejor el delete()
método de recolección en lugar de cargar los productos en un bucle (lo cual todos sabemos es una muy mala práctica)?
El objetivo principal es tener en cuenta estos puntos clave en el caso del desarrollo de un módulo: ¿hay casos particulares en los que no se puede usar el método walk
/ colección delete()
?
EDITAR: la razón definitivamente no se debe al catalog_controller_product_delete
envío del evento, ya que el mismo código se puede encontrar en varios lugares (verifique los massDelete
métodos) en el núcleo de Magento. He utilizado el ejemplo de productos para resaltar el rendimiento, ya que generalmente son las entidades más grandes.
delete()
realiza una consulta DELETE en lugar de cargar la colección y eliminar cada producto. Con eso realmente perderás los eventos.
getSingleton()
como medida de rendimiento, en lugar del uso obvio de la colección. Ah, y también es posible activar el evento con una colección, pero no con elwalk()
acceso directo.