【发布时间】:2018-10-30 03:22:32
【问题描述】:
我有一个关于代码优化的问题。 十多年来,除了简单的循环,我没有编写任何代码。
我创建了下面的代码,它运行良好,但对于我的需求来说速度非常慢。
本质上,我有 2 个 CSV 文件:
- 一个包含大约 500 000 条记录的源 CSV 文件,例如:att1、att2、source_id、att3、att4(实际上大约有 40 列)
- 一个包含大约 1.2 亿条记录的主 CSV 文件,例如:att1、att2、att3、main_id、att4(实际上大约有 120 列)
对于源文件中的每个 source_id,我的代码都会在主文件中解析 main_id == source_id 的所有行,并将这些行中的每一行写入一个新文件中。
你对我如何优化代码有什么建议吗?
<?php
$mf = "main.csv";
$mf_max_line_length = "512";
$mf_id = "main_id";
$sf = "source.csv";
$sf_max_line_length = "884167";
$sf_id = "source_id";
if (($mf_handle = fopen($mf, "r")) !== FALSE)
{
// Read the first line of the main CSV file
// and look for the position of main_id
$mf_data = fgetcsv($mf_handle, $mf_max_line_length, ",");
$mf_id_pos = array_search ($mf_id, $mf_data);
// Create a new main CSV file
if (($nmf_handle = fopen("new_main.csv", "x")) !== FALSE)
{
fputcsv($nmf_handle,$mf_data);
} else {
echo "Cannot create file: new_main.csv" . $sf;
break;
}
}
// Open the source CSV file
if (($sf_handle = fopen($sf, "r")) !== FALSE)
{
// Read the first line of the source CSV file
// and look for the position of source_id
$sf_data = fgetcsv($sf_handle, $sf_max_line_length, ",");
$sf_id_pos = array_search ($sf_id, $sf_data);
// Go trhough the whole source CSV file
while (($sf_data = fgetcsv($sf_handle, $sf_max_line_length, ",")) !== FALSE)
{
// Open the main CSV file
if (($mf_handle = fopen($mf, "r")) !== FALSE)
{
// Go trhough the whole main CSV file
while (($mf_data = fgetcsv($mf_handle, $mf_max_line_length, ",")) !== FALSE)
{
// If the source_id matches the main_id
// then we write it into the new_main CSV file
if ($mf_data[$mf_id_pos] == $sf_data[$sf_id_pos])
{
fputcsv($nmf_handle,$mf_data);
}
}
fclose($mf_handle);
}
}
fclose($sf_handle);
fclose($nmf_handle);
}
?>
【问题讨论】:
-
您的问题是您正在使用嵌套循环来查找您的连接。基本上,对于源文件中的每一行,您将遍历整个主文件。这意味着您最终将获得 60 万亿(500,000 * 120,000,000)次读取,而不是 1.205 亿(500,000 + 120,000,000)次读取。尝试在一个循环中将主文件的结果缓存到一个数组中,并以您正在搜索的索引的值为键。然后另一个循环可以使用简单的
isset检查该数组。 -
谢谢,我害怕加载 500 000 行(大约 1Gb 的数据)和 1.2 亿行(大约 25Gb)来炸毁我的笔记本电脑,但我可以设置一个有足够内存来处理的 VM它。