Підключаємо класи різних чином (php), блог го

Щось давненько ми тут не займалися дурницями.

Сьогодні ми будемо проводити тести з усіма можливими порушеннями їх чистоти і нахабно маніпулювати статистикою.

Питання: як правильно підключати в своєму проекті класи, щоб при цьому заощадити час на їх підключення.

  • Старий добрий autoload (). як у всіх нормальних людей.
  • Взяти і зібрати всі класи в один файл, як багато вчать.
  • Підключати потрібні класи явно через require_once ().
  • І новомодна штучка: Phar-архів.
  • Phar-архів ще можна робити не простий, а з стисненням (GZ або BZ2).
  • Ну і phar'ом також два варіанти: autoload () або пряме підключення вкладених файлів.
  • І поверх цього можна акселератором якимось пошаманити.

Інструменти

Інструменти для тестів тут: на гітхабе.

Запуск ./create.php створює каталог test. а в ньому такі речі.

Каталог classes

Структура наших тестованих класів. Все по стандарту PSR-0.

Створюється 5 просторів імен з випадковими іменами. У кожному створюється 5 випадкових класів з випадковим набором методів.

І в кожному з глобальний просторів створюється ще 5 вкладених і в них ще по 5 класів.

Разом 150 класів. Стандартний такий посередній фреймворк.

файл full.php

Весь «фреймворк» одним файлом.

Файл вийшов розміром 85 K. А загальна вага каталогу (за рахунок великої кількості маленьких файлів) 725 К (файлова система ext4).

Кілька сірників вже заощадили.

файл exec.php

Це виконуваний скрипт, в якому викликаються потрібні класи.

Щоб домогтися якоїсь подоби зі звичайними сценаріями: в одному сценарії задіяні не всі класи фреймворка, а тільки 50 (третина). Але до кожного класу може бути кілька звернень.

Робота з кожним класом проста: викликається статичний метод, який виконує найпростіше арифметичне дію. Таким чином час витрачений на роботу з класами не повинно набагато перевершити час витрачений на їх підключення (яке ми і тестуємо).

Phar-архіви

З каталогу classes створюється три phar-архіву: phar-none.phar. phar-gz.phar. phar-bz.phar (без компресії, gz, bz).

Розмір phar-node.phar. 99 К. Більше ніж full.php за рахунок додаткової інформації.

Стислі файли: 51 К (gz) і 61 К (bz). Нормальні то архіватори стискають і трохи краще.

(Потрібно розширення Phar і повинна бути скинута настройка phar.readonly в php.ini)

Файли req.php і phar-req.php

У req.php підключаються всі використовувані в exec.php файли (50 штук).

У phar-req.php теж саме, тільки підключаються вони не з каталогу, а з phar-архіву.

Після створення тестового каталогу запускаємо з консолі тести. /run.php [test].

Аргумент [test] може бути наступним:

autoload. підключення файлів з каталогу за допомогою автолоада.
Автолоад простий: замінює NS1 \ NS2 \ Class на DIR / NS1 / NS2 / Class.php. перевіряє наявність файлу і підключає його.

full. підключення одного великого файлу.

req. підключення потрібних файлів через require_once

phar-auto. підключення з phar через автолоад.

phar-req. підключення потрібних файлів з phar через require_once.

phar-gz і phar-bz. підключення через автолоад зі стислих архівів.

Так як в циклі проганяти такі тести безглуздо, та й взагалі чистотою тестів тут вже і не пахне, просто викликаємо кілька разів з консолі (результати все одно завжди виявляються схожими).

результати

У мене вийшло таке (P. Dual Core 2,8Гц, ubuntu, php 5.5.1):

псевдоаналітиків

Автолоад vs збірка в один файл

Мало того, що збірка в один файл виїла в 3 рази більше пам'яті (підключаємо всі класи, коли потрібна лише третина), так вона ще й за часом програла автолоаду з яким покликана боротися.

Подальші тести показали, що в часі збірка наближається до автолоаду при підключенні близько 50% від загальне числа класів, а потім починає обходити його.

Автолоад vs requre

require очікувано обійшло autoload.
Логічно, адже при автолоаде відбувається багато різних рухів, які закінчуються все тим же require.

Однак, різниця всього лише 10%.
І це при тому, що в тесті require_once для кожного класу викликається тільки один раз (в реальному проекті, якщо перед кожним класом спочатку підключати потрібні йому, один і той же клас буде запитуватися багаторазово і require_once кожен раз буде перевіряти чи підключено вже файл чи ні ).
Крім того, наші тестові файли маленькі. На великому файлі, його підключення і розбір зайняло б набагато більше.

Це до теми оптимізації пошуку класів: можна прибрати з автолоада file_exists (), можна сканувати каталоги і збирати карту класів в масив і використовувати його, ще можна багато чого зробити. Але всі ці оптимізації будуть тільки в межах цих 10%. Просте явне require по швидкості ніяк не оминути.

Phar цілком собі бадьоренько.

Трохи повільніше і трохи більше пам'яті хоче.
Але по споживанню пам'яті до варіанту із збіркою в один файл йому далеко.
Хоча тут теж один файл.

Стиснення: gzip дещо випередив bz2 і тут (вище у нього вийшов менший розмір файлу).

Однак, при стисненні значно знижується швидкість доступу.
Та й ступінь стиснення, як бачили вище, якось не дуже (більш того, при стисненні нормальним архиватором стисненого phar'а результат виходить більше, ніж стиснення нестислого).

Так що використовувати стислі phar'и я б не рекомендував.
Хоча, можливо, який-небудь опкешер вирішив би цю ситуацію.

Zend Opcache

Ну і бажано все це протестувати з усіма опкешерамі, акселераторами і тому подібним.
Але ставити їх все ліниво, так що перевірив тільки на opcache.

При запуску тестів з консолі слід не забути включити в php.ini опцію opcache.enable_cli.

Включення opcahce призвело до двократного падіння споживання пам'яті.

Щодо швидкості точних чисел немає, так як результати почали сильно коливатися, а наші методи не дозволяють усереднити їх по великій кількості тестів.

Однак, коливаються результати приблизно в тих же пропорціях. Максимально: відповідає часу без opcahce, мінімально: в два-три рази менше.
Коли Ви телефонуєте з консолі можуть іноді значно перевершувати за часом виклики через браузер.

1. Нічого паритися через нісенітниці. Оптимізація все одно незначна в порівнянні зі звичайним часом виконання сценарію.

2. autoload () - найкраще і найзручніше рішення. Тим більше всі стандарти типу PSR тепер зав'язані на нього.

3. Проводити збірку декількох файлів в один, побудова карт класів і т.п. можна тільки на продакшені при Деплой.
Коли все більш істотне вже оптимізовано.
При розробці ж: геморою багато, а толку мало.

4. Складання кількох файлів в один дає результат, тільки якщо кожен раз використовується хоча б половина вкладених файлів.

5. phar - добре (для поставляються бібліотек, які не потрібно змінювати).

6. Стиснутий phar - не так добре.

7. Opcahce цілком собі рулить.

Відмова від зобов'язань