Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP联盟\Csv what';更快:使用foreach循环或Reader::fetchOne(n)进行迭代?_Php_Csv - Fatal编程技术网

PHP联盟\Csv what';更快:使用foreach循环或Reader::fetchOne(n)进行迭代?

PHP联盟\Csv what';更快:使用foreach循环或Reader::fetchOne(n)进行迭代?,php,csv,Php,Csv,哪个更快: $csvReader = League\Csv\Reader::createFromPath($csvFile->getPathname()); // a) foreach ($csvReader as $row) { $this->processRow($row); } // or b) $rowIndex = 0; while (true) { $row = $csvReader->fetchOne($rowIndex); if (

哪个更快:

$csvReader = League\Csv\Reader::createFromPath($csvFile->getPathname());

// a)
foreach ($csvReader as $row) {
    $this->processRow($row);
}

// or b)
$rowIndex = 0;
while (true) {
    $row = $csvReader->fetchOne($rowIndex);

    if (!$row) {
        break;
    }

    $this->processRow($row);

    $rowIndex += 1;
}
我检查了
League\Csv
的源代码,发现解决方案
a)
使用前向读取迭代器,而解决方案
b)
使用php的
LimitIterator(iterator())
。所以问题最终归结为:php的LimitIterator的偏移量设置有多快。如果它迭代初始项以跳过内部迭代器到偏移量所需的项,那么很明显,解决方案
a)
更快

我更喜欢使用解决方案
b)
,因为它可以让我更好地控制迭代(例如跳过标题行)。但是如果性能如此有害,那么我会使用解决方案
a)
(并手动跳过标题行)

我很确定解决方案
b)
的速度非常慢。我希望有比我更聪明的人来证实这一点,因为我无法从源代码中完全了解使用csv文件时,
LimitIterator
如何倒回偏移量。

解决方案
a)
更快。对于1k行文件,
a)
以0.07秒的速度运行,
b)
以6.75秒的速度运行

要手动跳过解决方案
a)
中的标题,我执行了以下操作:

$rowsIterator = $csvReader->getIterator();
$rowsIterator->current(); // I don't know why this is needed, but without this, it doesn't skip the header.
$rowsIterator->next();

while ($rowsIterator->valid()) {
    $this->processRow($rowsIterator->current());
    $rowsIterator->next();
}
对于感兴趣的读者:以下方法不起作用或不能让我满意:

// c) foreach loop seems to be rewinding the iterator's pointer to the beginning at start
$rowsIterator = $csvReader->getIterator();
$rowsIterator->current();
$rowsIterator->next();

foreach ($rowsIterator as $row) {
    $this->processRow($row);
}

// d) `if` statement every iteration takes time
foreach ($csvReader as $rowIndex => $row) {
    if ($rowIndex === 0) {
        continue;
    }

    $this->processRow($row);
}

// e) LimitIterator is slower than my final solution for some reason
foreach (new LimitIterator($csvReader->getIterator(), 1) as $row) {
    $this->processRow($row);
}

那么你做了什么基准?我没有做任何tbh。我宁愿知道它在内部是如何工作的,而不是依赖于基准测试。但既然你提到了它,我实际上可以对一百万行csv执行这段代码。针对1k行csv保留一个扇区。差别是巨大的。解决方案
a)
完成大约需要0.07秒,而解决方案
b)
完成大约需要6.75秒。这几乎意味着,对任何实质性内容使用
LimitIterator
都是不可能的。嗯,我想我当时回答了我自己的问题。除非其他人有什么要补充的。像这样的微优化很少对总体性能/容量有任何重大影响-但我从您的回答中注意到,它确实在这里有非常重大的影响(!),这意味着优化文件迭代器的空间很大。