Más contenido relacionado Similar a Способы оптимизации работы с памятью в Magento 2 (20) Способы оптимизации работы с памятью в Magento 21. © 2017 Magento, Inc. Page | 1 ‘17
СПОСОБЫ ОПТИМИЗАЦИИ
И РАБОТА С ПАМЯТЬЮ
В MAGENTO 2
2. © 2017 Magento, Inc. Page | 2 ‘17
Разработчики в компании «Amasty»
Обуховский Евгений
Харлап Станислав
5. © 2017 Magento, Inc. Page | 5 ‘17
ПИКОВОЕ ЗНАЧЕНИЕ
ИСПОЛЬЗУЕМОЙ ПАМЯТИ В КБ
тестовое веб-приложение с запросами к БД
6. © 2017 Magento, Inc. Page | 6 ‘17
ПАМЯТЬ И МАССИВЫ
<?php
$startMemory = memory_get_usage();
$array = range(1, 100000);
echo memory_get_usage() - $startMemory, ' bytes';
7. © 2017 Magento, Inc. Page | 7 ‘17
ОЧЕВИДНЫЙ
ОТВЕТ
800 000 байт
Около 780 Кб
8. © 2017 Magento, Inc. Page | 8 ‘17
4,00 Мб
ПРАВИЛЬНЫЙ
ОТВЕТ
В 5 раз больше ожидаемого результата
9. © 2017 Magento, Inc. Page | 9 ‘17
СТРУКТУРА ЭЛЕМЕНТА МАССИВА
typedef struct _Bucket {
zend_ulong h;
zend_string *key;
zval val;
} Bucket;
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. © 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. © 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. © 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. © 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
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 и один указатель
для каждого элемента.
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);
}
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. © 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. © 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. © 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. © 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. © 2017 Magento, Inc. Page | 26 ‘17
КЕШИРОВАНИЕ МЕТОДОВ
private function getUrlModifier() {
if ($this->urlModifier === null) {
$this->urlModifier = MagentoFrameworkAppObjectManager::
getInstance()->get(MagentoFrameworkUrlModifierInterface::class);
}
return $this->urlModifier;
}
29. © 2017 Magento, Inc. Page | 29 ‘17
МАССИВЫ VS МОДЕЛИ
$collection->getData() $collection->getItems()
ЛЕГКО ТЯЖЕЛО