【问题标题】:Faster parsing of array in php在 php 中更快地解析数组
【发布时间】:2013-12-23 01:42:21
【问题描述】:

我有一个包含 40 000 行的 CSV 文件,我将所有行加载到一个数组中,然后我使用此函数返回一个子数组,其中包含我需要的值...这是代码

<?php

//----------------------------------------------
function query_array($theArray,$theQuery,$col){

    $return = array();

    foreach($theArray as $subarray){
        if ($subarray[$col] == $theQuery) {
            $return[] = $subarray;
            }
    }

    return $return;
}

//----------------------------------------------
function parse_csv_file($csvfile) {

    $csvData = file_get_contents($csvfile);
    $lines = explode("\n", $csvData);
    $array = array();
    foreach ($lines as $line) {
        $array[] = str_getcsv($line);
    }

    return $array;
}

//----------------------------------------------
function echo_array($theArray) {

    $return = "";

    foreach ($theArray as $key => $value) {
        $result = implode(' ', $value);
        $return .= '(# '. $key .')-> '. $result .'<br/>';
    }

    return $return;

}

//----------------------------------------------
$starttime = microtime(TRUE);

$fileName = "the-path-to-my-file/PHOTOS.TXT";
$basename = basename($fileName);
$MyQuery = "8370336";
$myCol = 0;

echo 'Query : Find : '. $MyQuery . ' dans la collone : '. $myCol . ' du fichier : '. $basename .'<br/><br/>';

$outputArray = parse_csv_file($fileName);
$slimDownArray = query_array($outputArray, $MyQuery, $myCol);
echo echo_array($slimDownArray);

$endtime = microtime(TRUE);
$totaltime = $endtime - $starttime;
echo '<br/>Temp execution : '. round($totaltime,2) . ' second<br/>'."\n";

?>

所以要从 40 000 行 csv 中获取第 23 个条目,需要 1.7 秒...问题,我们可以让它更快吗?,少于 1 秒?

【问题讨论】:

  • 您知道在加载 CSV 文件之前需要第 23 个条目吗?如果是这样,您可以限制一开始读取的 CSV 文件的数量。
  • 或者,如果您看到条目时可以识别它,则没有理由保存每​​一行。您只需遍历这些行并忘记它们,直到找到您需要的行
  • @squeamishossifrage 这太过分了,除非需要经常这样做。如果没有更多信息,我们不知道,但您可能是对的。
  • @Tim 以这种方式查找单条记录需要 1.7 秒。他有4万条记录!数据库一点也不矫枉过正。它可以是一个轻量级的数据库,比如 SQLite。他会在很短的时间内得到结果。
  • @menardmam 我不知道我为什么要帮助你这样做。其他人是对的。如果你不想要数据库服务器,那么 SQLite 有 PHP 函数。

标签: php jquery arrays csv request


【解决方案1】:

您不需要最初将所有行加载到数组中。只需在开始时构建“过滤”数组即可。

$field_delimiter = ",";  // or "|" or any other delimiter
function parse($file_in) {

    $fh = fopen($file_in, "r");
    $data_arr = array();
    while (($line = fgetcsv($fh, 1024, $field_delimiter)) !== false) {

         //add data into your array in here;
         //anytime you want to skip a line of data, just use:  continue;

    }
    return $data_arr;
}

【讨论】:

    【解决方案2】:

    对象或类方法会更好/更灵活,但这种方法应该比您拥有的更快。我只是将常量用于几件事。 $line 的东西只有在你关心行号的情况下才会出现:

    function query_csv($query, $col) {
    
        static $fp;
    
        if(!$fp) {
            $fp = fopen(CSV_NAME, 'r');
        }    
        $line = 0;
        $return = array();
    
        while(($data = fgetcsv($fp, 0, CSV_DELIM, CSV_ENC)) !== false) {
            if($data[$col] == $query) {
                //$return[$line] = $data; //if you want array keyed by line
                $return[] = $data;
            }
            $line++;
        }
        return $return;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-13
      • 1970-01-01
      • 2016-03-09
      • 1970-01-01
      • 2013-04-13
      • 2011-04-22
      • 2015-11-23
      • 2011-06-17
      相关资源
      最近更新 更多