В настоящее время я пытаюсь улучшить пару модулей в отношении производительности.
Некоторые из вас могут знать, как использовать walk()
метод сбора, который очень полезен, чтобы не зацикливаться на товарах напрямую.
Кроме того, благодаря @Vinai можно также использовать delete()
метод сбора данных .
Но я заметил, что собственные файлы Magento 1 не всегда используют любой из этих методов для удаления.
Один из худших кодов, который я видел, - это massDelete()
метод, из app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
которого продукты загружаются в цикл перед удалением .
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')->load($productId);
Mage::dispatchEvent('catalog_controller_product_delete', array('product' => $product));
$product->delete();
}
Поэтому я провел несколько тестов производительности, добавил несколько вызовов в журналы, чтобы проверить время и использование памяти для удаления 100 продуктов.
Тест 1: walk
метод
Я заменил оригинальный код, вставленный выше, этим кодом:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->walk('delete');
И мои результаты следующие на моем crappy dev сервере (в среднем по 10 тестам):
- Исходный код: 19,97 секунд, использовано 15,84 МБ
- Пользовательский код: 17,12 секунд, используется 15,45 МБ
Таким образом, для удаления 100 продуктов мой пользовательский код на 3 секунды быстрее и использует на 0,4 МБ меньше.
Тест 2: Использование delete()
метода сбора
Я заменил оригинальный код на этот:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->delete();
И умопомрачительные вот результаты:
- Исходный код: 19,97 секунд, использовано 15,84 МБ
- Пользовательский код: 1,24 секунды, 6,34 МБ используется
Поэтому при удалении 100 продуктов мой пользовательский код работает на 18 секунд быстрее и использует меньше 9 МБ.
Как указано в комментариях, похоже, что этот метод не вызывает события Magento (после загрузки, после удаления) и очистки индекса / кэша.
Вопрос
Итак, мой вопрос: есть ли причина, по которой основная команда Magento не использовала метод walk('delete')
или событие лучше, чем delete()
метод сбора вместо загрузки продуктов в цикле (что, как мы все знаем, очень и очень плохая практика)?
Главная цель - знать о таких ключевых моментах в случае разработки модуля: есть ли конкретные случаи, когда нельзя использовать метод walk
/ collection delete()
?
РЕДАКТИРОВАТЬ: причина определенно не в том, что catalog_controller_product_delete
событие отправляется, поскольку один и тот же код можно найти в нескольких местах (проверьте massDelete
методы) в ядре Magento. Я использовал пример продуктов, чтобы подчеркнуть производительность, поскольку они, как правило, являются крупнейшими организациями
delete()
делает запрос DELETE вместо загрузки коллекции и удаления каждого продукта. С этим вы действительно потеряете события.
getSingleton()
качестве показателя производительности вместо очевидного использования коллекции. Да, и событие можно вызвать с помощью коллекции, но не с помощьюwalk()
ярлыка.