1

Say I have a rather large associative array of 100k elements like so:

$resources = array(
'stone'=>'current_stone.gif',
'stick'=>'uglystick.jpg',
...
);

Stored in a file called resources.php and it will never change at runtime.

I would like to have this data in Zend opcache so as to share it across all processes (saving memory) and possibly speed up the lookup speed.

My current assumption is that, in this form, this array will not get stored in opcache as it's not defined as a static structure anywhere.

How would I go about making sure this data gets into opcache?

4

2 回答 2

5

上面的答案是错误的。变量存储在操作码缓存中。

您可以通过创建大量数据、将其存储在 PHP 文件中并使用 opcache_get_status() 检查缓存统计信息来测试它。结果包括列出所有缓存文件和已用内存的“脚本”数组。

我写了几个缓存文件,它们只有一个庞大的数组。其中之一是 24.1Mb

这是转储结果print_r(opcache_get_status())

Array
(
    [opcache_enabled] => 1
    ...
    [scripts] => Array
    (
        ...
        [/test/noto.php] => Array
            (
                [full_path] => /test/noto.php
                [hits] => 3
                [memory_consumption] => 24591120
                [last_used] => Sat Nov 24 21:09:58 2018
                [last_used_timestamp] => 1543086598
                [timestamp] => 1543086378
            )

        ...
    )
)

因此,它肯定与所有数据一起存储在内存中。

为了确保确实如此,我制作了几个文件,它们的数据总大小约为 300Mb。如果没有 opcache,加载它们大约需要 1.5 秒。然后在初始加载后,它会被缓存,加载所有数据需要 2 毫秒。相差近1000倍。

因此,将缓存存储在将由 Zend OPcache 缓存的 PHP 文件中并使用 include 包含它(try..catch(\Throwable $e)以避免错误)是迄今为止缓存数据的最有效方法。

于 2018-11-24T19:24:42.663 回答
2

不,您不能将变量存储在 OPcache 中,但类中的静态可以工作:

class Resource {
    static $image = [
        'stone'=>'current_stone.gif',
        'stick'=>'uglystick.jpg',
        ...
    ];
}
...
echo Resource::$image['stone'], "\n";

这保存了初始化数组的所有操作码,但 OPcache 仍会将 SMA 中已编译脚本中的 Resource::$image 版本深复制到进程空间中相应的类静态属性中,因此您仍然会有一份每个使用 Resource 的活动进程中的 HashTable - 尽管字符串本身将被实习,因此在所有使用此类的活动 php 请求中共享。

如果您使用类自动加载器来加载您的类,那么您甚至不需要做任何事情,只需引用,Resoure::$image...自动加载器就会为您完成映射。

于 2013-12-30T02:29:35.773 回答