Расширение класса внешними методами и переменными

Yoskaldyr

"Спамер"
Партнер клуба
Всегда есть последний return, где ты можешь написать new MyStatData(...) от всех накоплений.
Как я сказал выше - с иммутабл проблема расхода памяти. когда данных много - жопа. На объекты перешли с массивов, потому что расход памяти меньше. плюс появился автокомплит в коде, сложнее допустить ошибку при куче однотипных названий полей.

P.S. я знаю что пхп для стат расчетов не подходит, но это только небольшая часть приложения
 

Yoskaldyr

"Спамер"
Партнер клуба
И как оно помешает запушить? А если расширение не установят?
php скрипт на один из хуков гитлаба. Название не скажу. Было несколько лет назад (но точно не psalm) и оно было даже до того как сторм научился понимать эту аннотацию
 

Yoskaldyr

"Спамер"
Партнер клуба
Читаем внимательно исходные условия - огромное количество сырых данных.
я иммутабл вообще где только позволяет его использовать использую, но не работает это со сверх большими объектами с данными (особенно когда создание клона объекта через конструктор)
простая математика - если объектов несколько или несколько мутаций (клонирований) в пределах одного метода расход памяти - размер объекта * количество мутаций/объектов (и принудительный GC тут не поможет, т.к. память под данные выделена отдельно на каждый объект).
 

WMix

герр M:)ller
Партнер клуба
на старый обьект ссылка исчезнет же, и GC почистит
PHP:
class A{
    private $b = 'Hello'; // влепи сюда 100500 значений
   
    public function foo(){
        return new A;
    }
}
$max = 0;
$a = new A;
echo memory_get_usage(true)."\n"; // 262144
for($i = 0; $i<1000; $i++){
    $a = $a->foo();
    $max = max($max,  memory_get_usage(true));
}
echo $max."\n"; // 262144
 

fixxxer

К.О.
Партнер клуба
Я так понимаю, есть некий "калькулятор", в который загружается тяжелая стата, производится набор вычислений вызовом методов, и потом надо получить результат. На части это не делится, поскольку в любом вычислении может понадобиться все что угодно. Соответственно, есть некие методы, модифицирующие внутренний стейт, которые вызываются в произвольном порядке. Если сделать так, что этот "калькулятор" принимает стейт и возвращает новый, то возникает проблема с неэффективностью по памяти (ну, допустим, хотя не особо верится).

Окей, пусть он тогда держит стейт внутри, вызываем сколько угодно "модифицирующих" методов, а в конце вызываем метод, который "экспортирует" стейт, возвращая immutable value object.
 

Yoskaldyr

"Спамер"
Партнер клуба
@WMix пример в корне не верный. в данном примере как раз все будет очищаться по GC, т.к. одновременно живет только 2 инстанса и не важно насколько большой будет цикл.
и во вторых память при нехватке выделяется блоками (по сколько вот точно не помню), так что даже если несколько таких небольших объектов создать, то memory get usage будет одинаковый.
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
простая математика - если объектов несколько или несколько мутаций (клонирований) в пределах одного метода расход памяти
PHP:
<?php

final class Foo
{
    private $bar;

    public function withBar(int $bar)
    {
        $foo = clone $this;
        $foo->bar = $bar;
        return $foo;
    }

    public function __clone()
    {
        echo __METHOD__, PHP_EOL;
    }

    public function __destruct()
    {
        echo __METHOD__, PHP_EOL;
    }
}

function test()
{
    $foo = new Foo();
    $foo = $foo->withBar(42);

    echo 'test()', PHP_EOL;
}

test();
PHP:
Foo::__clone
Foo::__destruct
test()
Foo::__destruct
Деструктор вызывается еще до того, как объект покинет метод.

Но даже безотносительно этого — рассуждения на уровне оптимизации скриптов заменой двойных кавычек на апострофы — о каких таких проблемах памяти ты говоришь? Придумал вчера вечером с пивом в руках?
 

Yoskaldyr

"Спамер"
Партнер клуба
Окей, пусть он тогда держит стейт внутри, вызываем сколько угодно "модифицирующих" методов, а в конце вызываем метод, который "экспортирует" стейт, возвращая immutable value object.
Ну учитывая что в таком случае будет только 2-й перерасход памяти и полностью прогнозируемый.

@Вурдалак, ну просто фейспалм. пример полностью аналогичный примеру @WMix
А теперь замени
PHP:
    $foo = new Foo();
    $foo = $foo->withBar(42);
на
PHP:
    $foo = new Foo();
    $bar = $foo->withBar(42);
https://3v4l.org/ZVkRY

Главный плюс мутабельности, в данном случае, что нельзя случайно сделать дубликат объекта. Это проблема как раз редких ошибок, которые вылезут на реальных данных а не в тестах (ну или тесты делать на реальных данных)
 

fixxxer

К.О.
Партнер клуба
Ну учитывая что в таком случае будет только 2-й перерасход памяти и полностью прогнозируемый.
Плюс к тому, это разрывает жесткую связь между внутренней структурой и "внешним" представлением. Допустим, понадобилось поменять внутреннее состояние для оптимизации алгоритмов подсчета этой самой статистики. Если внешний код ходит в паблики, для обратной совместимости придется делать "денормализацию" после каждой модификации, чтобы эти паблики отражали актуальное состояние. А при явном экспортировании можно замапить что угодно как угодно, сохраняя обратную совместимость при любых изменениях внутри.
 

Вурдалак

Продвинутый новичок
Главный плюс мутабельности, в данном случае, что нельзя случайно сделать дубликат объекта.
У тебя там взрыв происходит, ты пишешь скрипт на PHP для поддержания работы ядерного реактора с памятью в 50 мегабайт? Хватит сказки рассказывать.
 

fixxxer

К.О.
Партнер клуба
Не хочешь, чтобы клонировали - сделай private __clone, тоже мне проблема.

А делать методы, неявно возвращающие клон, у мутабельного объекта - это да, это странно и чревато.
 

Yoskaldyr

"Спамер"
Партнер клуба
@fixxxer Под клонированием я подразумевал любое создание мутированной копии что через clone(), что через конструктор, но как результат в памяти фактически 2 полных независимых экземпляра.

@WMix в моем случае, учитывая специфику расчетов и учитывая что объекты в пхп присваиваются по ссылке мне выгоднее мутабельные объекты. Необходим один и тот же объект с одними и теми же данными (конечный результат мутаций) в разных списках, с последующим проходом по этим спискам.

Здесь на форуме эджкейсы всегда вызывают срач :)
Но ведь всегда возникают нюансы, когда количество каких нибудь данных превышает какой-то порог и в зависимости от инструмента это может быть как несколько лямов (чего либо) так и всего несколько тысяч. И абсолютно всегда приходится искать оптимальный в данном конкретном случае вариант и чаще всего этот вариант будет очень компромиссным и часто совсем не таким красивым как хотелось бы.

@Вурдалак так отстаивает иммутабельные объекты, будто я хоть что-то плохое написал насчет них. Я лишь описал проблему конкретного случая когда иммутабельность не подходит. Иммутабельность - это всего лишь инструмент, как и мутабельность. И как его использовать должен решать каждый сам в зависимости от конкретной ситуации. И да было бы значительно лучше если бы была нормальная иммутабельность в пхп, а не те костыли что есть сейчас. Но с другой стороны как-то все смогли прожить все это время и без нее. И все недостатки большинство и так знает, как и все плюсы. По крайней мере надеюсь на это.
 

Вурдалак

Продвинутый новичок
Да мне вообще наплевать на иммутабельность, меня лишь напрягают бесконечные сказки от людей, кто оправдывает наличие мутаторов. Нужно честно признаться: «лень мне иммутабельность поддерживать», нет нужно рассказывать про память, про сложность, про единорогов.
 

Yoskaldyr

"Спамер"
Партнер клуба
@Вурдалак Если не было задач связанных с большими кусками данных, не значит что у других их нет. В некоторых сферах развлечений данных очень и очень много и большая их часть обрабатывается не на пхп. Но т.к. пхп основной стек, то кое что надо обрабатывать и в нем. И пхп для этого не сильно приспособлен (как и точные вычисления, тоже не самая удобная вещь)
 

fixxxer

К.О.
Партнер клуба
Если я правильно догадываюсь, о какого рода задаче речь, я бы такое не стал писать на PHP. Тот же go изучается за пару дней, и на третий-четвертый уже пишешь вполне себе идиоматичный код, на себе недавно проверил.
 

Yoskaldyr

"Спамер"
Партнер клуба
Если я правильно догадываюсь, о какого рода задаче речь, я бы такое не стал писать на PHP. Тот же go изучается за пару дней, и на третий-четвертый уже пишешь вполне себе идиоматичный код, на себе недавно проверил.
Это легаси. и все что должно работать быстро и так давно написано и продолжает пилиться на го и ноде.
Статистик или как сейчас модно называть датасаентист пишет на питоне насколько знаю.
А всякая ненагруженная часть, на пхп, т.к. исторически сложилось и явно дешевле и проще найти разрабов. Плюс плотная интеграция с коммьюнити (как раз где xenforo, т.к. нормальных альтернатив ему просто нет). Потому и пхп :(
 

fixxxer

К.О.
Партнер клуба
явно дешевле и проще найти разрабов
Да как сказать. Нормальные (не 20-летние) senior-ы и хорошие мидлы примерно одинаково на любом стеке. Насчет проще - да фиг там, найти PHP-разработчика, который способен понять архитектуру, отличную от того, что в мануалах на фреймворки, довольно сложно.
А дешевые разработчики всегда дороже в конечном итоге (не, понятно, что иногда надо какое-нибудь говно типа блога на вордпрессе склепать, я не про такие ситуации, такое вообще проще на апворк отдать).
 
Последнее редактирование:
Сверху