我很感激任何帮助。
我有7个单独的数组,大约有。每个数组中有90,000个数字(让我们称之为arrays1-arrays7)。每个数组本身都没有重复的数字。但是,阵列之间可能存在重复。例如,array2没有重复项,但可以使用与arrays3和arrays4相同的数字。
问题: 一旦所有7个阵列合并,我试图识别所有重复3次的数字。
我必须进行1000次计算,需要15分钟,但这不行,因为我必须运行40次 - 代码:
如果您知道其他最适合此类计算的语言,请告知我们。任何扩展建议,如redis或gearman都是有帮助的。
for($kj=1; $kj<=1000; $kj++)
{
$result=array_merge($files_array1,$files_array2,$files_array3,$files_array4,$files_array5,$files_array6,$files_array7);
$result=array_count_values($result);
$fp_lines = fopen("equalTo3.txt", "w");
foreach($result as $key => $val)
{
if($result[$key]==3)
{
fwrite($fp_lines, $key."\r\n");
}
}
fclose($fp_lines);
}
我也用字符串尝试了下面的代码,但是array_map调用和array_count值调用需要17分钟:
for($kj=1; $kj<=1000; $kj++)
{
$result='';
for ($ii = 0; $ii< 7; $ii++) {
$result .= $files_array[$hello_won[$ii]].'\r\n';
}
$result2=explode("\n",$result);//5mins
$result2=array_map("trim",$result2);//11mins
$result2=array_count_values($result2);//4-6mins
$fp_lines = fopen("equalTo3.txt", "w");
foreach($result2 as $key => $val)
{
if($result2[$key]==3)
{
fwrite($fp_lines, $key."\r\n");
}
}
fclose($fp_lines);
unset($result2);
/////////////////////////////////////////////// ////
@piumin @ailvenge @scunliffe @ this.lau_ @monocell感谢所有发帖的人!我正在处理你的所有建议,并在我完成所有答案后明天接受答案。非常感谢你!答案 0 :(得分:6)
array_merge()
在数组中有更多元素的速度要慢得多,因为(来自php.net):
如果输入数组具有相同的字符串键,则后面的值 该密钥将覆盖前一个密钥。但是,如果是数组 包含数字键,后面的值不会覆盖原始值 值,但会附加。
带有数字键的输入数组中的值将重新编号 在结果数组中从零开始递增键。
所以这个函数实际上是在做一些条件语句。您可以使用正常添加替换数组合并,包括循环(foreach或任何其他)和[]
运算符。你可以编写一个模拟array_merge的函数,比如(使用引用不复制数组..):
function imitateMerge(&$array1, &$array2) {
foreach($array2 as $i) {
$array1[] = $i;
}
}
你会看到速度的增加真的很难。
答案 1 :(得分:1)
这可能都错了,请看最后一次修改
我也认为array_merge
是问题,但我的建议是实施
一个函数直接计算几个数组中的值而不是先合并。
这取决于你在数组中有多少重叠。如果重叠
非常小,然后这可能不会比合并快得多,但有重要意义
重叠(rand(0, 200000)
以填充数组,当我尝试)这将更快。
function arrValues($arrs) {
$values = array();
foreach($arrs as $arr) {
foreach($arr as $key => $val) {
if(array_key_exists($key, $values)) {
$values[$val]++;
} else {
$values[$val] = 1;
}
}
}
return $values;
}
var_dump(arrValues(array
($files_array1
,$files_array2
,$files_array3
,$files_array4
,$files_array5
,$files_array6
,$files_array7
)));
在我的机器上计算大约需要0.5秒,然后另外2秒用于打印这些东西。
-edit -
我也不清楚为什么你做同样的事情1000次?阵列是否不同 每次还是什么?说一下这个原因可能会给人们额外的想法...
- 再次编辑 -
经过一番探索之后,我再也不相信array_merge了。你没有 有足够的重叠,从直接计算一切中受益。有你 调查机器上的可用内存?对我来说,将7个阵列与90k元素合并 每个需要约250M。如果你允许php使用这么多内存,我假设你 因为你没有得到任何分配错误,那么问题可能是内存 根本不可用,你会遇到很多页面错误?如果这不是问题那么 在什么样的机器和你使用的PHP版本?我已经测试了你的 5.5和5.4上的原始代码和修复内存问题它也运行在大约0.5秒。那 每次迭代都会介意你。现在如果你在同一个PHP脚本中执行1000次 这需要一段时间。考虑到你每次都分配所有这些内存,更是如此。
我相信你真的应该考虑把东西放在数据库中。鉴于你的数字,你似乎总共有5亿行。这在php中处理得非常多。数据库使其变得简单。
答案 2 :(得分:0)
我建议更换
foreach($result as $key => $val)
{
if($result[$key]==3)
{
fwrite($fp_lines, $key."\r\n");
}
}
类似
$res = array_keys(array_filter($result, function($val){return $val == 3;}));
fwrite($fp_lines, implode("\r\n", $res));