Jos*_*eph 5 optimization perl refactoring multithreading
我之前从未使用过线程,但我想我可能遇到过这样的机会:
我编写了一个脚本,通过一组~500个Excel文件进行咀嚼,并使用Parse :: Excel从工作簿中的特定工作表中提取值(平均每个工作簿两个工作表;每个工作表提取一个单元格.)
现在运行它,我只是逐个浏览文件数组并从文件中提取相关信息,大约需要45分钟才能完成.
我的问题是:这是一个使用线程的机会,并且一次有多个文件被点击*,或者我应该只接受45分钟的运行时间?
(* - 如果这是对我可以用线程做什么的严重误解,请说出来!)
提前感谢您提供的任何指导!
编辑 - 添加示例代码.下面的代码是一个sub,在foreach循环中为存储在数组中的每个文件位置调用:
# Init the parser
my $parser = Spreadsheet::ParseExcel->new;
my $workbook = $parser->parse($inputFile) or die("Unable to load $inputFile: $!");
# Get a list of any sheets that have 'QA' in the sheet name
foreach my $sheet ($workbook->worksheets) {
if ($sheet->get_name =~ m/QA/) {
push @sheetsToScan, $sheet->get_name;
}
}
shift @sheetsToScan;
# Extract the value from the appropriate cell
foreach (@sheetsToScan) {
my $worksheet = $workbook->worksheet($_);
if ($_ =~ m/Production/ or $_ =~ m/Prod/) {
$cell = $worksheet->get_cell(1, 1);
$value = $cell ? $cell->value: undef;
if (not defined $value) {
$value = "Not found.";
}
} else {
$cell = $worksheet->get_cell(6,1);
$value = $cell ? $cell->value: undef;
if (not defined $value) {
$value = "Not found.";
}
}
push(@outputBuffer, $line);
Run Code Online (Sandbox Code Playgroud)
线程(或使用多个进程fork
)允许您的脚本同时使用多个 CPU。对于许多任务来说,这可以节省大量“用户时间”,但不会节省“系统时间”(甚至可能会增加系统时间来处理启动和管理线程和进程的开销)。以下是线程/多重处理没有帮助的情况:
当算法的每个步骤都依赖于前面的步骤时,脚本的任务不适合并行化
与创建和管理新线程或新进程的开销相比,您的脚本执行的任务快速且轻量级
您的系统只有一个 CPU 或者您的脚本只能使用一个 CPU
您的任务受到与 CPU 不同的资源的限制,例如磁盘访问、网络带宽或内存 - 如果您的任务涉及处理通过慢速网络连接下载的大文件,那么您的网络是瓶颈,并且处理该文件在多个 CPU 上没有帮助。同样,如果您的任务消耗了 70% 的系统内存,那么使用第二个和第三个线程将需要对交换空间进行分页,并且不会节省任何时间。如果您的线程竞争某些同步资源(文件锁、数据库访问等),并行化的效率也会降低。
您需要考虑系统上的其他用户 - 如果您使用计算机上的所有核心,那么其他用户的体验将会很差
[仅添加线程]您的代码使用任何非线程安全的包。大多数纯 Perl 代码都是线程安全的,但使用 XS 的包可能不是
[补充]当你仍在积极开发你的核心任务时。并行代码的调试要困难得多
即使这些都不适用,有时也很难判断任务将从并行化中受益多少,唯一确定的方法是实际实现并行任务并对其进行基准测试。但您所描述的任务看起来可能是并行化的良好候选者。