我有一个PHP脚本,它从file1 1M行加载一些数据,还有一个比30M行更大的文件,而不是需要根据第一个文件的数据查找。 所以我将1M行加载到数组中,即$ array [$ STRINGLOOKUP] = 1;迭代超过30M的行并在$ array上的array_key_exist上进行查找。
问题是我的笔记本电脑32位PHP(2GB限制)一切正常,但在生产64位PHP时,存在内存不足问题(也限制2GB)。我听说使用pack()函数可以降低内存消耗。有没有人尝试过,是否可能/值得尝试?
<?php
$index=array();
foreach($lines as $line){
$index[$line]=1
}
foreach($lines30M as $line){
list($junk1,$lookup,$junk2) = explode("\t",$line,3);
if(array_key_exist($index[$lookup]){
//do something
}
}
?>
答案 0 :(得分:2)
有没有人尝试过,是否可能/值得尝试?
没有
您正在尝试编写DBMS。你认为你可以比编写MySQL,MariaDB,SQLLite,PostgreSQL,MongoDB,GDBM的人做得更好吗?
答案 1 :(得分:0)
将1M放入数组可能不是最有效的内存方式。每个阵列单元的要求都会达到数十个字节。另外,在下面的代码中你需要两次:
foreach($lines as $line){
$index[$line]=1
}
因为最终会有两个数组:$lines
和$index
都包含相同的信息。为什么不坚持使用in_array()
代替array_key_exists()
?
但我同意其他评论,这显然是数据库的工作。有什么像SQLite通过PDO?你有一天必须学习这些知识,一旦你知道如何做到这一点。
答案 2 :(得分:0)
我尝试使用pack()作为练习但是它比普通数组需要更多内存但是有一个SplFixedArray类使用更少的内存。虽然这并没有为Integers使用更少的内存,但使用的固定数组长度比普通数组消耗更少的内存。
以下是内存使用的示例代码
<?php
$mem = memory_get_usage(1);
$array = array();
for($i=0;$i<100000;$i++){
$array[$i]=1;
}
$mem1 = memory_get_usage();
echo ($mem1 - $mem)/1024/1024 . " Mb\n";
// 13.8 Mb
$array2 = array();
for($i=0;$i<100000;$i++){
$array2[$i]=pack('v',1);
}
$mem2 = memory_get_usage();
echo ($mem2 - $mem1)/1024/1024 . " Mb\n";
// 17.0 Mb
$array3 = new SplFixedArray(100000);
for($i=0;$i<100000;$i++){
$array3[$i]=1;
}
$mem3 = memory_get_usage();
echo ($mem3 - $mem2)/1024/1024 . " Mb\n";
// 5.3 Mb
如果您事先知道数组的大小并且可以使用整数作为键(SplFixedArray仅支持整数作为键),这可以节省大量内存。