Вы можете использовать простые объекты, чтобы иметь такой же эффект, как символы в ruby. Некоторые функции базы данных имеют опцию FETCH_OBJECT для эмуляции этого эффекта.
class StoreMe {
public $A;
public $B;
public $C;
public $D;
}
Основным преимуществом символов является использование в качестве хэш-ключей для оптимизации производительности и использования памяти. Поскольку PHP использует «Копировать при записи» для хранения переменных, строки могут быть эквивалентны символам в ruby. Но PHP использует некоторый тип таблицы перевода, чтобы получить индекс для массива из хеш-ключа. Таким образом, каждый небольшой массив имеет определенные издержки.
Testscript
Я написал этот небольшой скрипт, чтобы проверить объем памяти с помощью PHP.
error_log("Start: " . memory_get_usage());
$iterations = 10000;
$hash = [];
for ($i=0; $i<$iterations; $i++) {
$hash[] = [
"A" => "Test",
"B" => "Test",
"C" => "Test",
"D" => "Test",
];
}
error_log("String: " . memory_get_usage());
$hash = null;
error_log("Reset: " . memory_get_usage());
$hash = [];
for ($i=0; $i<$iterations; $i++) {
$hash[] = [
"Test",
"Test",
"Test",
"Test",
];
}
error_log("Raw: " . memory_get_usage());
$hash = null;
error_log("Reset: " . memory_get_usage());
$hash = [];
$copy = [
"Test",
"Test",
"Test",
"Test",
];
for ($i=0; $i<$iterations; $i++) {
$hash[] = $copy;
}
error_log("Copy: " . memory_get_usage());
$hash = null;
error_log("Reset: " . memory_get_usage());
$hash = [];
for ($i=0; $i<$iterations; $i++) {
$store = new StoreMe();
$store->A = "Test";
$store->B = "Test";
$store->C = "Test";
$store->D = "Test";
$hash[] = $store;
}
error_log("Object: " . memory_get_usage());
$hash = null;
$store = null;
error_log("Reset: " . memory_get_usage());
Вот результаты с официальными изображениями Docker для PHP. Правильное значение - это потребление памяти в байтах.
PHP 5,6
Start: 225680
String: 8837400
Reset: 226088
Raw: 8837400
Reset: 226088
Object: 5580488
Reset: 1209264
PHP 7,0
Start: 355400
String: 4643840
Reset: 355400
Raw: 4643840
Reset: 355400
Copy: 884216
Reset: 355776
Object: 2127096
Reset: 478656
PHP 7.1
Start: 355336
String: 883776
Reset: 355336
Raw: 883776
Reset: 355336
Copy: 883776
Reset: 355336
Object: 2126656
Reset: 478216
Заключение
Объектам нужно меньше памяти, чем ожидалось. Но PHP 5.6, похоже, имеет проблемы с сборкой мусора с использованием объектов. Результаты PHP 7.1, похоже, являются своего рода оптимизацией компилятора, потому что нет разницы в «Копировании при записи» и создании массивов.