Perl创建对象的速度非常慢

lim*_*eri 3 perl performance object

我有一个perl脚本,它从数据库读取大约50,000行,并将它们存储在散列数组中.标准DBI代码.我宁愿将数据放入可以非常干净地传递给其他代码模块的对象,而不是直接在哈希上工作.我正在阅读的表格中有15多列.我的代码基本上看起来像:

my $db = DBI->connect(); # Just pretend you see a proper DBI connect here
my $resultSet = $db->selectall_arrayref($sql);
$db->disconnect();

# Here's where the problem starts.
my %objects;
for my $row (@{$resultSet}) {
    my ($col1, $col2, ..., $col15) = @{$row};
    my %inputHash;
    $inputHash{col1} = $col1 if $col1;
    ...
    $inputHash{col15} = $col1 if $col15;
    my $obj = Model::Object->new(%inputHash);
    $objects{$col1} = $obj;
}
return values %objects;
Run Code Online (Sandbox Code Playgroud)

它将东西收集到哈希中以消除选择中的重复.问题开始于评论下面的循环中,"这是问题开始的地方".我在循环中添加了一条消息,为每100个创建的对象记录一行.前100个对象是在5秒内创建的.接下来的100分钟需要16秒.达到300需要30多秒.这是多达9000个对象,需要12分钟以上才能创建100个对象.我认为50,000个对象不足以产生这些问题.

正在创建的Model :: Object是一个具有每个属性的getter和setter的类.它有一个新方法和一个序列化方法(本质上是一个toString)就是这样.这没有逻辑.

我在Windows笔记本电脑上运行ActiveState Perl 5.16,内存为8 GB,i7处理器(3年)和具有合理空间的SSD驱动器.我在具有相同版本Perl的Linux机器上看到过这个,所以我不认为这是硬件.我需要留在AS Perl的5.16.任何有关如何提高性能的建议都将受到赞赏.谢谢.

Pat*_* S. 5

首先:描述你的程序!你已经把它缩小到一个子,用Devel::NYTProf(例如)你可以将它缩小到那个罪魁祸首.

以下是我方的一些一般性考虑因素:

只是从浏览它看起来,一些可能的减速因素立即浮现在脑海中,但你不能确定你是否不描述你的程序:

Mayhe散列分配需要太长时间.随着%objects哈希的增长,perl将稳定地分配更多内存.您可以预先设置$objects哈希的大小.此功能在此处记录.由于这是一个内存分配问题,如果您使用太小的数据集进行配置,则无法识别此问题.

# somewhere outside of the loop
keys(%objects) = $number_of_rows * 1.2;
# the hash should be a little bigger than the objects to be stored in it
Run Code Online (Sandbox Code Playgroud)

其次,可能是对象创建需要太长时间.看看Model::Object.我不知道那里有什么,所以我不能对此发表评论.但大多数情况下你应该考虑将其%inputHash作为参考传递.使用Model::Object->new(%inputHash);,您将键和值放在堆栈上,然后检索它,最坏的情况是my %options = @_;.通过该移动,您可以重新计算每个键的哈希值.

也许你可以想出办法$inputHash完全摆脱小.我很快就会想出一些基于definednes的方法,但是你正在检查它是否正确(你确定这是正确的,顺便说一句,"0"是假的,例如).

但同样,最重要的是:描述您的计划.也许采用较小的数据集,但是你无法清楚地看到内存分配问题.但是通过分析,您将看到,此时您的程序将花费最多的时间.

The perldoc有关于加快你的计划的话题.它也有一个关于分析的好章节.

  • ***...在最糟糕的情况下,作为`my%options = @_;`.通过该移动,您可以重新计算每个键***的非常好的点 (2认同)