performance - Perl 创建对象非常慢

标签 performance perl 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;

它将内容收集到哈希中以消除选择中的重复项。问题开始于“这是问题开始的地方”的评论下方的循环。我在循环中放了一条消息,为每 100 个创建的对象记录一行。前 100 个对象在 5 秒内创建。接下来的 100 个需要 16 秒。达到 300 又花了 30 秒。最多 9000 个对象,创建 100 个对象需要 12 分钟以上。我认为 50,000 个对象不足以产生此类问题。

正在创建的 Model::Object 是一个类,每个属性都有 getter 和 setter。它有一个新方法和一个序列化方法(本质上是一个 toString),仅此而已。没有逻辑。

我在 Windows 笔记本电脑上运行 ActiveState Perl 5.16,配备 8 GB 内存、i7 处理器(3 岁)和空间合理的 SSD 驱动器。我在装有相同版本 Perl 的 Linux 机器上看到过这个,所以我认为这不是硬件问题。我需要继续使用 AS Perl 的 5.16。任何有关如何提高性能的建议将不胜感激。谢谢。

最佳答案

首先:分析您的程序!您已经将它缩小到一个子程序,Devel::NYTProf (例如)您可以将范围缩小到罪魁祸首。

以下是我的一些一般考虑:

只要看一眼,一些可能的减慢因素就会立即浮现在脑海中,但如果您不分析您的程序,您将无法确定:

Mayhe 散列分配花费的时间太长。随着 %objects 散列的增长,perl 将稳步分配更多内存。 您可以预先设置您的 $objects 散列的大小。此功能是 documented here .由于这是一个内存分配问题,如果您使用太小的数据集剖析,您将不会意识到这一点。

# 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

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

也许您可以想出一种方法来完全摆脱小的$inputHash。我很快只能想出一些方法,这些方法将基于 definednes,但你正在检查真实性(你确定那是对的,顺便说一句?“0”例如,是错误的)。

但同样,最重要的是:剖析您的程序。也许采用较小的数据集,但那时您将无法清楚地看到内存分配问题。但是通过分析,您会准确地看到您的程序在哪个点花费的时间最多。

The perldoc has something to say about speeding up your program .它也有一个关于分析的精彩章节。

关于performance - Perl 创建对象非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30553574/

相关文章:

ios - 检查图像是否全白的最佳性能方法?

java - 在java中比较两个日期的最佳方法

perl - 为什么 perltidy 要进入标准输出?

javascript - 为什么我无法向 div 添加事件监听器?

javascript - 从二维数组创建对象数组

performance - WebAPI 在同一台服务器上,即使在其上应用了 SSL,也可以通过 http 而不是 https 访问它吗?

perl - 无论创建范围如何,Perl 格式是否都绑定(bind)到文件句柄?

perl - 如何在perl中将任何日期时间转换为微秒

jquery - 如何使用 jquery 插件将对象保存到 session

java - 合并锁会降低性能吗?