文本文件(实际上是.dat)中包含的数据如下:
LIN*1234*UP*abcde*33*0*EA
LIN*5678*UP*fghij*33*0*EA
LIN*9101*UP*klmno*33*23*EA
实际上在这个文件中有超过50万行这样的行。
这是我现在使用的:
//retrieve file once
$file = file_get_contents('/data.dat');
$file = explode('LIN', $file);
...some code
foreach ($list as $item) { //an array containing 10 items
foreach($file as $line) { //checking if these items are on huge list
$info = explode('*', $line);
if ($line[3] == $item[0]) {
...do stuff...
break; //stop checking if found
}
}
}
问题是它运行得太慢了——每次迭代大约1.5秒。我单独确认了这不是"……"做的东西…这影响了速度。相反,它是搜索正确的项目。
我怎样才能加快速度?谢谢你。
如果每个条目都在自己的行上,而不是将整个内容加载到内存中,使用fgets()
可能会更好:
$f = fopen('text.txt', 'rt');
while (!feof($f)) {
$line = rtrim(fgets($f), "'r'n");
$info = explode('*', $line);
// etc.
}
fclose($f);
PHP文件流是缓冲的(~8kB),所以在性能方面应该是不错的。
另一部分逻辑可以这样重写(而不是多次迭代文件):
if (in_array($info[3], $items)) // look up $info[3] inside the array of 10 things
或者,如果$items
被适当索引:
if (isset($items[$info[3]])) { ... }
file_get_contents
将整个文件作为数组加载到内存中&然后你的代码对它起作用。从PHP fgets
官方文档中改编这个示例代码应该会更好:
$handle = @fopen("test.txt", "r");
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
$file_data = explode('LIN', $buffer);
foreach($file_data as $line) {
$info = explode('*', $line);
$info = array_filter($info);
if (!empty($info)) {
echo '<pre>';
print_r($info);
echo '</pre>';
}
}
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail'n";
}
fclose($handle);
}
使用您的数据的上述代码的输出是:
Array
(
[1] => 1234
[2] => UP
[3] => abcde
[4] => 33
[6] => EA
)
Array
(
[1] => 5678
[2] => UP
[3] => fghij
[4] => 33
[6] => EA
)
Array
(
[1] => 9101
[2] => UP
[3] => klmno
[4] => 33
[5] => 23
[6] => EA
)
但是仍然不清楚你丢失的代码,因为那行声明:
foreach ($list as $item) { //an array containing 10 items
那似乎是另一个真正的瓶颈。
当您执行file_get_contents
时,它会将内容加载到内存中,因此您只能想象该进程可能会占用多少资源。更不用说你还有一个嵌套循环,那就是(O)n^2
如果可能的话,您可以拆分文件或使用fopen
, fgets
和fclose
逐行读取它们。
如果我是你,如果我真的需要速度,我会使用C++
或Go
等其他语言。