This package provides you with a simple PHP trait, which adds high-performance memoization to your classes!
$ composer require laracraft-tech/memoize
The memoize
method accepts a callable
.
use LaracraftTech\Memoize\HasMemoization;
$myClass = new class()
{
use HasMemoization;
public function getNumber(): int
{
return $this->memoize(function () {
return rand(1, 10000);
});
}
};
No matter how many times you run $myClass->getNumber()
you'll always get the same number.
The memoize
method will only run once per combination of use
variables the closure receives.
$myClass = new class()
{
use HasMemoization;
public function getNumberForLetter($letter)
{
return $this->memoize(function () use ($letter) {
return $letter . rand(1, 10000000);
});
}
}
So calling $myClass->getNumberForLetter('A')
will always return the same result, but calling $myClass->getNumberForLetter('B')
will return something else.
Some memoization packages uses the arguments of the containing method for the once per combination idea.
We think this feels a bit unintuitive and in certain circumstances will affect performance. So we use the use
variables of the closure as the once per combination key. As a fallback, if you like/need to, we also let you fully self define your once per combination key in a second optional parameter of the closure.
use LaracraftTech\Memoize\HasMemoization;
$myClass = new class()
{
use HasMemoization;
public function processSomethingHeavy1($someModel)
{
// ...
$relation = $this->memoize(function () use ($someModel) {
return Foo::find($someModel->foo_relation_id);
}, $someModel->foo_relation_id); // <--- custom once per combination key
// ...
}
// you could also do something like this (maybe more convinient)
public function processSomethingHeavy2($someModel)
{
// ...
$foo_relation_id = $someModel->foo_relation_id;
$relation = $this->memoize(function () use ($foo_relation_id) {
return Foo::find($foo_relation_id);
});
// ...
}
// this would work but will lose performance on each new $someModel even foo_relation_id would be the same
public function processSomethingHeavy3($someModel)
{
// ...
$relation = $this->memoize(function () use ($someModel) {
return Foo::find($someModel->foo_relation_id);
});
// ...
}
}
So when calling $myClass->processSomethingHeavy1(SomeModel::find(1))
the variable $relation
will always have the same value like in $myClass->processSomethingHeavy1(SomeModel::find(2))
as long as they have the same foo_relation_id
. In some other memoization packges you would lose performance here, cause the containing method parameter ($someModel) has changed... Note that processSomethingHeavy3
would also lose performance, even though the foo_relation_id
would be the same, cause here also the changed $someModel would be used as the combination key and that model would have at least a different id.
You can globally enable or disable the memoize cache by setting MEMOIZATION_GLOBALLY_DISABLED
to true
in your .env
file.
If you only want to disable to memoize cache for a specifiy class, do something like this:
use LaracraftTech\Memoize\HasMemoization;
class MyClass
{
use HasMemoization;
public function __construct()
{
$this->disableMemoization();
}
}
Please see the changelog for more information on what has changed recently.
$ composer test
Please see contributing.md for details and a todolist.
If you discover any security related issues, please email zacharias.creutznacher@gmail.com instead of using the issue tracker.
MIT. Please see the license file for more information.