4

我正在为某人对数百万个旧日志条目进行数据挖掘,并且真的想在这件事上使用 PHP 来提供材料,以便轻松地将它们链接到现有的 PHP 系统。

我在终端(OSX 10.8)的 PHP 5.4.4 中运行此代码:

// Settings
ini_set('error_reporting', E_ALL); // Shows all feedback from the parser for debugging
ini_set('max_execution_time', 0); // Changes the 30 seconds parser exit to infinite
ini_set('memory_limit', '512M'); // Sets the memory that may be used to 512MegaBytes


echo 'Start memory usage: '.(memory_get_usage(TRUE) / 1024)."\n";

$x = Array();
for ($i = 0; $i < 1e7; $i++) {
    $x[$i] = 1 * rand(0, 10);
    //unset($x[$i]);
}

echo 'End memory usage: '.(memory_get_usage(TRUE) / 1024)."\n";
echo 'Peak memory usage: '.(memory_get_peak_usage(TRUE) / 1024)."\n";

这是一千万次循环的简单测试。与在 Python 中使用字典相比,泄漏真的很糟糕 :(。

当我取消引用 unset() 函数来测试用法时,它立即变成了独角兽和彩虹。所以强制释放内存似乎进展顺利。

有什么办法我仍然可以在 512M 内存限制内维护 10-50 百万个数组条目?

我也无法想象我什么时候会用这些循环做一些正则表达式..

4

2 回答 2

3

使用SplFixedArray是因为您确实需要了解PHP 数组(和值)到底有多大?(提示:大!)

$t = 1e6;
$x = array();
for($i = 0; $i < $t; $i ++) {
    $x[$i] = 1 * rand(0, 10);
}

输出

Start memory usage: 256
End memory usage: 82688
Peak memory usage: 82688

$t = 1e6;
$x = new SplFixedArray($t);
for($i = 0; $i < $t; $i ++) {
    $x[$i] = 1 * rand(0, 10);
}

输出

Start memory usage: 256
End memory usage: 35584
Peak memory usage: 35584

但更好的是我认为你应该考虑一个基于内存的数据库,比如REDIS

于 2013-02-14T17:54:28.260 回答
0

如果 SplFixedArray 对您不起作用,我强烈建议使用 RabbitMQ -> http://www.rabbitmq.com/tutorials/tutorial-one-php.html

RabbitMQ 比人们通常想象的更易于配置和使用,并且它有一个很好的 PHP 库。

使用 RabbitMQ,您的脚本可以快十倍、二十倍、一百倍(取决于您设置的消费者数量),您还可以管理任意数量的数据。

我曾使用 RabbitMQ 导入数百万行来检索有关在丹麦注册的所有汽车的信息,想象一下这有多大。

于 2014-11-24T14:36:09.200 回答