请参见下面的旧答案。
我将此答案的发现转化为一个插件,并在与Grinnz在IRC上讨论后,作为Mojolicious::Plugin::Renderer::WithoutCache发布到CPAN上,他们鼓励发布。
您可以像这样使用它:
use Mojolicious::Lite;
plugin 'Renderer::WithoutCache';
它将创建一个什么也不做的新缓存对象,并将其全局安装到渲染器中。这样,它就不需要像我的初始答案那样每次都创建。
理论上,这应该比 Grinnz的方法(更明智)更快,而且由于您明确不想缓存,显然希望尽可能快,对吧?据说更快,因为真正的 Mojo::Cache 仍然需要去尝试设置缓存,但然后会中止,因为没有更多的空闲键,并且它还会尝试每次从缓存中查找值。
我使用 Dumbbench 和 Benchmark 进行了基准测试。它们两个都显示出可忽略的结果。我每个运行了几次,但它们波动很大,不清楚哪个更快。我包括了一次运行的输出,其中我的实现更快,但它仍然显示出差异微小。
使用 Dumbbench 进行基准测试:
use Dumbbench;
use Mojolicious::Renderer;
use Mojolicious::Controller;
use Mojolicious::Plugin::Renderer::WithoutCache::Cache;
my $controller = Mojolicious::Controller->new;
my $renderer_zero_keys = Mojolicious::Renderer->new;
$renderer_zero_keys->cache->max_keys(0);
my $renderer_nocache = Mojolicious::Renderer->new;
$renderer_nocache->cache( Mojolicious::Plugin::Renderer::WithoutCache::Cache->new );
my $bench = Dumbbench->new(
target_rel_precision => 0.005,
initial_runs => 5000,
);
$bench->add_instances(
Dumbbench::Instance::PerlSub->new(
name => 'max_keys',
code => sub {
$renderer_zero_keys->render( $controller, { text => 'foobar' } );
}
),
Dumbbench::Instance::PerlSub->new(
name => 'WithoutCache',
code => sub {
$renderer_nocache->render( $controller, { text => 'foobar' } );
}
),
);
$bench->run;
$bench->report;
__END__
max_keys: Ran 8544 iterations (3335 outliers).
max_keys: Rounded run time per iteration: 5.19018e-06 +/- 4.1e-10 (0.0%)
WithoutCache: Ran 5512 iterations (341 outliers).
WithoutCache: Rounded run time per iteration: 5.0802e-06 +/- 5.6e-09 (0.1%)
使用Benchmark进行基准测试:
use Benchmark 'cmpthese';
use Mojolicious::Renderer;
use Mojolicious::Controller;
use Mojolicious::Plugin::Renderer::WithoutCache::Cache;
my $controller = Mojolicious::Controller->new;
my $renderer_zero_keys = Mojolicious::Renderer->new;
$renderer_zero_keys->cache->max_keys(0);
my $renderer_nocache = Mojolicious::Renderer->new;
$renderer_nocache->cache( Mojolicious::Plugin::Renderer::WithoutCache::Cache->new );
cmpthese(
-5,
{
'max_keys' => sub {
$renderer_zero_keys->render( $controller, { text => 'foobar' } );
},
'WithoutCache' => sub {
$renderer_nocache->render( $controller, { text => 'foobar' } );
},
}
);
__END__
Rate max_keys WithoutCache
max_keys 190934/s -- -2%
WithoutCache 193846/s 2% --
我认为在大量调用的高负载环境中,这可能会产生影响,但这很难证明。因此,如果您不想考虑缓存的内部情况,这个插件可能会有用。
旧回答:
查看 Mojolicious::Plugin::EPRenderer 后我发现有一个 cache
。它是一个 Mojo::Cache 实例,具有方法 get
、set
和 max_keys
,并继承自 Mojo::Base(就像 Mojolicious 中的所有东西一样)。
New answer:
通过查看 Mojolicious::Plugin::EPRenderer 我发现有一个名为 cache
的缓存。它是一个 Mojo::Cache 实例,拥有 get
、set
和 max_keys
等方法,并且像 Mojolicious 中的所有东西一样继承自 Mojo::Base。
:EPRenderer获取一个$renderer
, 它是一个Mojolicious::Renderer,它持有Mojo::Cache实例。我使用Data::Printer查看了$c
,发现有一个$c->app
持有所有这些信息。
知道这一点后,你可以很容易地创建自己的缓存类,什么都不做。
package Renderer::NoCache;
use Mojo::Base -base;
sub get {}
sub set {}
sub max_keys {}
现在将其插入到
$c
中。
package Foo;
use Mojolicious::Lite;
get '/' => sub {
my $c = shift;
$c->app->renderer->cache( Renderer::NoCache->new );
$c->render(template => 'foo', name => 'World');
};
app->start;
__DATA__
Hello <%= $name =%>.
现在每次尝试获取或设置缓存时都不会有任何反应。它会尝试缓存,但永远找不到任何东西。
当然,每次创建一个新对象并不是很好。最好在启动时只创建一次该对象,并将其放入内部永久版本的
app
中。由于您使用CGI,因此可能不会有什么区别。
你也可以直接对
Mojo::Cache
中的
get
进行猴子补丁。这种更加hacky的方法将实现相同的效果:
package Foo;
use Mojolicious::Lite;
*Mojo::Cache::get = sub { };
get '/' => sub {
my $c = shift;
$c->render(template => 'foo', name => 'World');
};
app->start;
但要注意:我们刚刚禁用了使用 Mojo::Cache 的应用程序中每个缓存的获取。这可能不是您想要的。