gpt4 book ai didi

php - 比较两个大文件需要四个多小时

转载 作者:搜寻专家 更新时间:2023-10-31 00:31:14 24 4
gpt4 key购买 nike

我有一家在线商店,每天更新大约 15,000 种产品。目前我每天都会上传新列表,但它会带来一些问题(比如停机时间是一个大问题),我想提出一个替代方案。我创建了一个脚本来移动“昨天”的产品列表并下载今天的产品列表。然后我逐行比较这两个文件,看看需要删除、修改和创建的内容。这将使我能够以最少的工作量执行更新,无需停机,因为一切都将通过 CRON 作业在幕后发生,这就是应该如何完成的。

我遇到的问题是这个过程需要四个多小时才能完成,而且我不确定我正在做的事情是否是最有效的方法。我的第一个想法是用 C++ 编写一些东西,但我不确定与 PHP 相比会快多少。

我的问题是:

• 这是最有效的方法吗?

• PHP 是执行此操作的最佳语言吗?

这是我编写的处理下载和比较的脚本:

public function __construct($url, $user, $pass)
{
$this->logger = new KLogger("/opt/lampp/htdocs/lea/logs/master.log" , KLogger::INFO);

/* increase execution time and server memory limit */
ini_set('max_execution_time', 14400);
ini_set('memory_limit', '-1');

/* set veriables */
$this->ftp = ftp_connect($url);
$this->login = ftp_login($this->ftp, $user, $pass);

$this->old = file('/opt/lampp/htdocs/lea/products/new/temp/rsr_inventory.txt');
$this->new = file('/opt/lampp/htdocs/lea/products/new/rsr_inventory.txt');

$this->list = array();

$this->start_time = date('Hi');

$this->counter = 0;
}

public function download($to, $from)
{
// move current file to new location to get new file ready
$this->logger->LogInfo('move yesterday\'s products list');
rename('/opt/lampp/htdocs/lea/products/new/temp/rsr_inventory.txt', '/opt/lampp/htdocs/lea/products/new/rsr_inventory.txt');

// get list from rsr
$this->logger->LogInfo('get new list from rsr');
if(ftp_get($this->ftp, $to, $from, FTP_BINARY))
{
return true;
}
return false;
}

public function update()
{
// initialize process
$this->logger->LogInfo('update process initialized');

for($i = 0; $i < count($this->new); $i++)
{
$new[$i] = explode(';', $this->new[$i]);
$response = $this->_match($new[$i]);
if($response[0])
{
if(trim($response[2]) != trim($new[$i][5]) || trim($response[3]) != trim($new[$i][8]))
{
$this->list[$this->counter][0] = $response[1];
$this->list[$this->counter][1] = 'update';
$this->list[$this->counter][2] = trim($response[2]);
$this->list[$this->counter][3] = trim($response[3]);
$this->counter++;
}
}
else
{
$this->list[$this->counter][0] = $response[1];
$this->list[$this->counter][1] = 'create';
$this->list[$this->counter][2] = trim($response[2]);
$this->list[$this->counter][3] = trim($response[3]);
$this->counter++;
}
}
if(count($this->list) > 0)
{
//csv
$this->logger->LogInfo('create update.csv');

$updates = fopen('/opt/lampp/htdocs/lea/products/new/updates.csv', 'w');
foreach($this->list as $fields)
{
fputcsv($updates, $fields);
}
fclose($updates);
}

$this->logger->LogInfo('product update process complete');
$this->__mail();

}

private function _match($item)
{
for($j = 0; $j < count($this->old); $j++)
{
$old[$j] = explode(';', $this->old[$j]);

if($item[0] === $old[$j][0])
{
return array(true, $item[0], $old[$j][5], $old[$j][8]);
}
}
return array(false, NULL, NULL, NULL);
}

这是我每天收到的 products.txt 文件的示例(我只显示 10 种产品,但大约有 15,000 种(缺少很多东西;价格、数量等...,但是我缩短了所有内容,因为显示这些并不重要):

511-10010-019-L-XL;844802282208;5.11 RECON ANKLE SOCK BLK L/XL; 
511-10010-036-L-XL;844802282246;5.11 RECON ANKLE SOCK SHADOW L/XL;
511-10010-132-LXL;844802334662;5.11 RECON ANKLE SOCK TIMBER L/XL;
511-10010-200-L-XL;844802282222;5.11 RECON ANKLE SOCK FATIGUE L/XL;
511-10011-019-L-XL;844802276382;5.11 COLD WEATHER OTC SOCK BLK L/XL;
511-10012-019-L-XL;844802276429;5.11 COLD WEATHER CREW SOCK BLK L/XL;
511-30012-019-M;844802269650;5.11 WOMENS HOLSTER SHIRT BLK M;
511-40011-010-L;844802016148;5.11 HOLSTER SHIRT L WHITE;
511-40011-010-M;844802016131;5.11 HOLSTER SHIRT M WHITE;
511-40011-010-XL;844802016155;5.11 HOLSTER SHIRT XL WHITE;
511-40011-010-XXL;844802016162;5.11 HOLSTER SHIRT 2XL WHITE;

最佳答案

我认为您的问题是您正在进行 15000 x 15000 次比较(因此对数据进行了 2.25 亿次操作)。

如果您改为创建一个映射(换句话说,PHP 中的数组),并使用一些唯一标识符作为旧的和新的索引。那是 30k 次操作,然后遍历一个列表,检查另一个列表是否包含相同的内容。那是另外 15K 次操作。总共 45K 次操作,而不是 225M 次操作。

我并不是说做数据库的建议是个坏主意,但花费过多的时间显然是算法+数据结构选择不当造成的。

关于php - 比较两个大文件需要四个多小时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34385247/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com