Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Способы оптимизации работы с памятью в Magento 2

62 views

Published on

Общая краткая информация по тому, как работает PHP с памятью. Сравнение объема памяти (в байтах) различных массивов, текстовых перменных и объектов. Также некоторые “фишки” для оптимизации расхода памяти в PHP.
Особенности оптимизации работы с памятью в M2. Сравнение некоторых типовых объектов классов по объемам памяти (Модели, Хелперы и т.д.). Способы обработки больших объемов данных в M2. Обработка объемных коллекций, загрузка и обработка их “пачками”. Оптимизация работы массивов объектов.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Способы оптимизации работы с памятью в Magento 2

  1. 1. © 2017 Magento, Inc. Page | 1 ‘17 СПОСОБЫ ОПТИМИЗАЦИИ И РАБОТА С ПАМЯТЬЮ В MAGENTO 2
  2. 2. © 2017 Magento, Inc. Page | 2 ‘17 Разработчики в компании «Amasty» Обуховский Евгений Харлап Станислав
  3. 3. © 2017 Magento, Inc. Page | 3 ‘17 ИСПОЛЬЗОВАНИЕ ПАМЯТИ В PHP
  4. 4. © 2017 Magento, Inc. Page | 4 ‘17
  5. 5. © 2017 Magento, Inc. Page | 5 ‘17 ПИКОВОЕ ЗНАЧЕНИЕ ИСПОЛЬЗУЕМОЙ ПАМЯТИ В КБ тестовое веб-приложение с запросами к БД
  6. 6. © 2017 Magento, Inc. Page | 6 ‘17 ПАМЯТЬ И МАССИВЫ <?php $startMemory = memory_get_usage(); $array = range(1, 100000); echo memory_get_usage() - $startMemory, ' bytes';
  7. 7. © 2017 Magento, Inc. Page | 7 ‘17 ОЧЕВИДНЫЙ ОТВЕТ 800 000 байт Около 780 Кб
  8. 8. © 2017 Magento, Inc. Page | 8 ‘17 4,00 Мб ПРАВИЛЬНЫЙ ОТВЕТ В 5 раз больше ожидаемого результата
  9. 9. © 2017 Magento, Inc. Page | 9 ‘17 СТРУКТУРА ЭЛЕМЕНТА МАССИВА typedef struct _Bucket { zend_ulong h; zend_string *key; zval val; } Bucket;
  10. 10. © 2017 Magento, Inc. Page | 10 ‘17 struct _zval_struct { zend_value value; union { struct { ... } v; uint32_t type_info; } u1; union u2; }; typedef union _zend_value { zend_long lval; double dval; zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zend_ast_ref *ast; zval *zv; void *ptr; zend_class_entry *ce; zend_function *func; struct { ... } ww; } zend_value; СТРУКТУРА ЭЛЕМЕНТА МАССИВА
  11. 11. © 2017 Magento, Inc. Page | 11 ‘17 ХРАНЕНИЕ МАССИВА. ИТОГИ. х64 х32 PHP 7 42 байт * 100 000 30 байт * 100 000 ИТОГ 4 Мб 3 Мб PHP 5.6 или меньше 144 байт * 100 000 76 байт * 100 000 ИТОГ 14 Мб 7.4 Мб
  12. 12. © 2017 Magento, Inc. Page | 12 ‘17 UNSET VS ПРИРАВНИВАНИЕ К NULL function memoryUsage($usage, $base_memory_usage) { printf("Bytes diff: %dn", $usage - $base_memory_usage); } $baseUsage = memory_get_usage(); $a = someBigValue(); unset($a); memoryUsage(memory_get_usage(), $baseUsage); $baseUsage = memory_get_usage(); $a = someBigValue(); $a = null; memoryUsage(memory_get_usage(), $baseUsage); Bytes diff: 0 Bytes diff: 76
  13. 13. © 2017 Magento, Inc. Page | 13 ‘17 <?php $startMemoryUsage = memory_get_usage(); $bigValue = str_repeat('BIG-BIG STRINGGGGGGGG',1024); $a = array($bigValue, $bigValue, $bigValue, $bigValue); foreach ($a as $k => $v) { $a[$k] = $bigValue; unset($k, $v); Printf("Bytes: %dn", memory_get_usage() – $startMemoryUsage); } echo 'After Foreach.' . PHP_EOL; Printf("Bytes: %dn", memory_get_usage() – $startMemoryUsage); ?> ПЕРЕДАЧА МАССИВОВ ПО ССЫЛКЕ Before Foreach Bytes: 61940 Bytes: 77632 Bytes: 93032 Bytes: 108432 Bytes: 123832 After Foreach Bytes: 61940
  14. 14. © 2017 Magento, Inc. Page | 14 ‘17 foreach ($a as $k => &$v) { $a[$k] = $bigValue; unset($k, $v); Printf("Bytes: %dn", memory_get_usage() - $startMemoryUsage); } ПЕРЕДАЧА МАССИВОВ ПО ССЫЛКЕ Bytes: 61940 Bytes: 61940 Bytes: 61940 Bytes: 61940 AFTER FOREACH BYTES: 61940
  15. 15. © 2017 Magento, Inc. Page | 15 ‘17
  16. 16. © 2017 Magento, Inc. Page | 16 ‘17 SPL FIXED ARRAY <?php $startMemory = memory_get_usage(); $array = new SplFixedArray(100000); for ($i = 0; $i < 100000; ++$i) { $array[$i] = $i; } Достигается тем, что SplFixedArray не нуждается в bucket структуре, только один zval и один указатель для каждого элемента.
  17. 17. © 2017 Magento, Inc. Page | 17 ‘17 ИСПОЛЬЗОВАНИЕ ПАМЯТИ В MAGENTO 2
  18. 18. © 2017 Magento, Inc. Page | 18 ‘17 СИСТЕМА ИНЪЕКЦИИ ЗАВИСИМОСТЕЙ public function __construct( MagentoFrameworkModelContext $context, MagentoFrameworkRegistry $registry, MagentoFrameworkStdlibDateTimeTimezoneInterface $localeDate, MagentoFrameworkViewDesignInterface $design, MagentoFrameworkModelResourceModelAbstractResource $resource = null, MagentoFrameworkDataCollectionAbstractDb $resourceCollection = null, array $data = [] ) { $this->_localeDate = $localeDate; $this->_design = $design; parent::__construct($context, $registry, $resource, $resourceCollection, $data); }
  19. 19. © 2017 Magento, Inc. Page | 19 ‘17 ПЛАГИНЫ: AROUND VS BEFORE + AFTER
  20. 20. © 2017 Magento, Inc. Page | 20 ‘17 ПЛАГИНЫ: AROUND VS BEFORE + AFTER
  21. 21. © 2017 Magento, Inc. Page | 21 ‘17 $collection->setPageSize(1000); $pages = $collection->getLastPageNumber(); for ($i = 1; $i <= $pages; $i++) { $collection->resetData(); $collection->setCurPage($i); $items = $collection->getData(); /** @var MagentoQuoteModelQuote $item */ foreach ($items as $customerItem) { $guests[] = $this->prepareGuestCustomerModel($customerItem); } $collection->clear(); } ОБРАБОТКА ДАННЫХ “ПАЧКАМИ”
  22. 22. © 2017 Magento, Inc. Page | 22 ‘17 public function deleteIndex($dimensions, Traversable $documents) { foreach ($this->batch->getItems($documents, $this->batchSize) as $batchDocuments) { $this->resource->getConnection()->delete($this->getTableName($dimensions), ['entity_id in (?)' => $batchDocuments]); } } public function getItems(Traversable $documents, $size){ $i = 0; $batch = []; foreach ($documents as $documentName => $documentValue) { $batch[$documentName] = $documentValue; if (++$i == $size) { yield $batch; $i = 0; $batch = []; } } if (count($batch) > 0) { yield $batch; }}
  23. 23. © 2017 Magento, Inc. Page | 23 ‘17 ОЧИСТКА КОЛЛЕКЦИИ $collection->setPageSize(1000); $pages = $collection->getLastPageNumber(); for ($i = 1; $i <= $pages; $i++) { $collection->resetData(); $collection->setCurPage($i); $items = $collection->getData(); /** @var MagentoQuoteModelQuote $item */ foreach ($items as $customerItem) { $guests[] = $this->prepareGuestCustomerModel($customerItem); } $collection->clear(); }
  24. 24. © 2017 Magento, Inc. Page | 24 ‘17 ЭКОНОМНАЯ ЗАГРУЗКА КОЛЛЕКЦИИ protected function _prepareCollection() { $collection = $this->_collectionFactory ->getReport('sales_order_grid_data_source') ->addFieldToSelect('entity_id') ->addFieldToSelect('increment_id') ->addFieldToSelect('customer_id') ->addFieldToSelect('created_at') ->addFieldToSelect('grand_total') ->addFieldToSelect('order_currency_code'); ...
  25. 25. © 2017 Magento, Inc. Page | 25 ‘17 private function getApplicableAttributeCodes(array $documentIds){ $attributeSetIds = $this->attributeSetFinder ->findAttributeSetIdsByProductIds($documentIds); $this->attributeCollection->getSelect() ->reset(MagentoFrameworkDBSelect::COLUMNS) ->columns('attribute_code'); return $this->attributeCollection->getConnection() ->fetchCol($this->attributeCollection->getSelect()); } ЭКОНОМНАЯ ЗАГРУЗКА КОЛЛЕКЦИИ
  26. 26. © 2017 Magento, Inc. Page | 26 ‘17 КЕШИРОВАНИЕ МЕТОДОВ private function getUrlModifier() { if ($this->urlModifier === null) { $this->urlModifier = MagentoFrameworkAppObjectManager:: getInstance()->get(MagentoFrameworkUrlModifierInterface::class); } return $this->urlModifier; }
  27. 27. © 2017 Magento, Inc. Page | 27 ‘17
  28. 28. © 2017 Magento, Inc. Page | 28 ‘17 ИСПОЛЬЗОВАНИЕ FLAT СТРУКТУРЫ
  29. 29. © 2017 Magento, Inc. Page | 29 ‘17 МАССИВЫ VS МОДЕЛИ $collection->getData() $collection->getItems() ЛЕГКО ТЯЖЕЛО
  30. 30. © 2017 Magento, Inc. Page | 30 ‘17 СПАСИБО!

×