【发布时间】:2011-04-01 11:44:53
【问题描述】:
我想知道是否有人可以阐明这个问题.. PHP 5.3.0 :)
我有一个循环,它正在获取 CSV 文件(大,200mb)的内容,处理数据,为 mysql 插入构建变量堆栈,一旦循环完成并创建变量,我将插入信息。
现在首先,mysql 插入执行得很好,没有延迟,一切都很好,但是延迟是 LOOP 本身,我最初使用 fgetcsv() 来读取 CSV 文件,但与 file_get_contents() 相比,这有严重延迟 - 所以我切换到 file_get_contents()。循环将在几秒钟内执行,直到我尝试添加一个函数(我还在循环内添加了没有该函数的表达式以查看它是否有帮助)以使用每行的 CSV 数据创建一个数组,这个是什么导致解析时间严重延迟! (基于这个 200mb 文件,差异约为 30 秒,但我猜这取决于 csv 文件的文件大小)
这里有一些代码,你可以看到我在做什么:
$filename = "file.csv";
$content = file_get_contents($filename);
$rows = explode("\n", $content);
foreach ($rows as $data) {
$data = preg_replace("/^\"(.*)\"$/","$1",preg_split("/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/", trim($data))); //THIS IS THE CULPRIT CAUSING SLOW LOADING?!?
}
运行上面的循环,几乎可以立即执行而无需行:
$data = preg_replace("/^\"(.*)\"$/","$1",preg_split("/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/", trim($data)));
我也尝试过创建如下函数(循环外):
function csv_string_to_array($str) {
$expr="/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/";
$results=preg_split($expr,trim($str));
return preg_replace("/^\"(.*)\"$/","$1",$results);
}
并调用函数而不是一个衬垫:
$data = csv_string_to_array($data);
再次没有运气:(
任何帮助将不胜感激,我猜测 fgetcsv 函数基于它导致的延迟以非常相似的方式执行,循环并从数据行创建一个数组。
丹尼
【问题讨论】:
-
您是否尝试过使用“for”循环而不是“foreach”?
-
已经尝试比较整个时间,直到您将数据放入您的方法与 fgetcsv() 的数组中? preg_replace 和 preg_split 是重量级函数,因为基于正则表达式处理字符串是一项 cpu 密集型任务。将函数调用放入另一个函数不能加快速度
-
我认为
fgetcsv会比那更快 -
艾默曼+1。为什么不能使用 fgetcsv(),danny,它专门用于读取/解析 CSV 数据? php.net/fgetcsv
-
@Wallgate - for 循环实际上比 foreach 慢,因为它需要更多的脚本操作码来处理计数器和条件。
标签: php performance loops