想象一下,你有一个整数的数组如下:
array(1, 2, 1, 0, 0, 1, 2, 4, 3, 2, [...] );
该整数下去高达一万个条目; 只有而不是被硬编码他们已经被预先生成并存储在JSON格式文件(大约2MB大小)。 这些整数的顺序是有意义的,我不能随机生成它的每一个时间,因为它应该是一致的,总是在同一个指标的值相同。
如果这个文件被读回PHP之后(例如,使用file_get_contents
+ json_decode
),它从700到900毫秒只是为了让数组回来- “好的”我想,“它可能是合理的,因为json_decode
具有解析约2万字,让我们缓存它”。 APC在大约68MB,可能是正常的,变量容器是一个大项缓存它。 然而,检索该阵列由APC回来也需要一些好的600毫秒这是在我的眼睛还太多。
编辑:APC不序列化/反序列化存储和检索的内容与一百万项数组是一个漫长而沉重的过程。
所以问题:
我应该想到这个等待时间,如果我打算装入一万个条目数组,无论数据存储或方法,在PHP? 据我了解APC存储的zval本身,所以从理论上APC检索它应该是尽可能快所能得到(没有分析,没有转换,无人接盘)
为什么是APC的东西,所以看似简单的这么慢?
有没有在内存使用PHP完全加载一万个条目阵列中的任何有效的方法? 假设RAM使用是没有问题的。
如果我再次访问基于指标(例如,装载从指数15指数76块)这个数组的唯一切片和从未真正拥有的全部内存阵列(是的,我明白这是做它的理智的方式,但我想知道所有的边),这将是对整个阵列的最有效的数据存储系统? 显然不是一个RDBM; 我想Redis的,但我会很高兴听到其他的想法。
再说整数都是0-15。 然后,你可以存储2每字节:
<?php
$data = '';
for ($i = 0; $i < 500000; ++$i)
$data .= chr(mt_rand(0, 255));
echo serialize($data);
要运行: php ints.php > ints.ser
现在你有一个包含百万个随机整数从0至15 500000字节字符串的文件。
载入:
<?php
$data = unserialize(file_get_contents('ints.ser'));
function get_data_at($data, $i)
{
$data = ord($data[$i >> 1]);
return ($i & 1) ? $data & 0xf : $data >> 4;
}
for ($i = 0; $i < 1000; ++$i)
echo get_data_at($data, $i), "\n";
我的机器上加载时间约为0.002秒。
当然,这可能不能直接适用于您的情况,但会超过一百万条目的臃肿PHP数组快得多。 坦率地说,具有阵列大型在PHP是从来没有适当的解决方案。
我并不是说这是妥善解决要么,但它肯定是可行的,如果它适合你的参数。
请注意,如果你的阵列有在0-255的整数范围,你可以摆脱包装的,只是访问数据为ord($data[$i])
在这种情况下,你的字符串是1M字节长。
最后,根据所述文档file_get_contents()
,PHP将存储器映射文件。 如果是的话,你最好的表现会转储原始字节的文件,并使用它,如:
$ints = file_get_contents('ints.raw');
echo ord($ints[25]);
这假定ints.raw
正好是一百万字节长。
APC存储序列化的数据,所以它有作为它被加载从APC回被解序列化。 这就是你的开销。
加载它的最有效的方法是写入文件作为PHP和include(),但你永远不会有含百万元素的数组任何效率水平......它需要的内存数量庞大,且它需要时间来加载。 这就是为什么数据库被发明出来,所以用什么数据库是你的问题?
编辑
如果你想加快序列化/反序列化,看一看的igbinary扩展
我不能随机生成它的每一个时间,因为它应该是一致的,总是在同一个指标的值相同。
你曾经在伪随机数读了? 有这家名为它解决此问题的种子的小东西。
此外基准你的选择和主张。 你有没有定时的的file_get_contents主场迎战json_decode? 还有就是要在此处进行存储和访问的成本之间的权衡。 例如。 如果您的号码是0到9(或0..255),那么它可能会更容易将它们存储在2MB的字符串,并在此使用的接入功能。 2MB将负载从FS或者APC是否更快。
正如马克说,这就是为什么数据库的创建 - 允许你搜索(和操纵,但你可能并不需要那个)的数据有效地根据你的正常使用模式。 这也将可能也比使用数组实现自己的搜索速度更快。 我猜我们正在谈论的地方接近(串行化之前)的数据2-300MB被序列化和反序列化你访问数组各一次。
如果你想加快速度,尽量到阵列中的每个元素分别分配 - 你可能会换函数调用开销序列化所花费的时间。 你也可以用自己的分机扩展此,包裹数据集中在一个小的检索界面。
我猜你之所以不能直接存储变量容器是因为它们含有的内部状态,你根本不能只是指向变量符号表上表。