linux perl占用大量资源_linux – 执行Perl脚本时解决内存不足错误

在尝试使用Perl脚本处理7.2GB文本文件时遇到内存不足错误。脚本创建了一个哈希映射来存储单词频率,作者建议通过设置输入记录分隔符为空格来分块读取文件,减轻内存压力。解决方案包括更改输入记录分隔符以按空格读取文件,并避免将长行一次性加载到内存。
摘要由CSDN通过智能技术生成

我正在尝试基于英语维基百科转储中找到的前100K单词构建一个n-gram语言模型.我已经使用用Java编写的修改过的XML解析器提取出纯文本,但需要将其转换为vocab文件.

为了做到这一点,我找到了一个据说可以完成工作的perl脚本,但缺乏如何执行的指令.毋庸置疑,我是Perl的全新手,这是我第一次遇到它的使用需求.

当我运行这个脚本时,我在两个独立的双核机器上使用这个7.2GB文本文件时遇到内存不足错误,该机器有4GB RAM和runnung Ubuntu 10.04和10.10.

当我联系作者时,他说这个脚本在带有4GB RAM的MacBook Pro上运行正常,当使用perl 5.12在6.6GB文本文件上执行时,内存总使用量大约为78 MB.作者还说,该脚本逐行读取输入文件,并在内存中创建一个hashmap.

该脚本是:

#! /usr/bin/perl

use FindBin;

use lib "$FindBin::Bin";

use strict;

require 'english-utils.pl';

## Create a list of words and their frequencies from an input corpus document

## (format: plain text, words separated by spaces, no sentence separators)

## TODO should words with hyphens be expanded? (e.g. three-dimensional)

my %dict;

my $min_len = 3;

my $min_freq = 1;

while (<>) {

chomp($_);

my @words = split(" ", $_);

foreach my $word (@words) {

# Check validity against regexp and acceptable use of apostrophe

if ((length($word) >= $min_len) && ($word =~ /^[A-Z][A-Z\'-]+$/)

&& (index($word,"'") < 0 || allow_apostrophe($word))) {

$dict{$word}++;

}

}

}

# Output words which occur with the $min_freq or more often

foreach my $dictword (keys %dict) {

if ( $dict{$dictword} >= $min_freq ) {

print $dictword . "\t" . $dict{$dictword} . "\n";

}

}

我正在通过命令行通过mkvocab.pl corpus.txt执行此脚本

附带的额外脚本只是一个正则表达式脚本,用于测试撇号的位置以及它们是否符合英语语法规则.

我认为内存泄漏是由于不同的版本,因为我的机器上安装了5.10.所以我升级到5.14,但错误仍然存​​在.根据free -m,我的系统上有大约1.5GB的可用内存.

由于我完全不熟悉语言的语法和结构,您能否指出问题区域以及问题存在的原因以及如何解决问题.

解决方法:

如果单词中有一些重复,则可以将7,2Gb文件加载到哈希中,例如,发生了17,000次等等,但似乎相当多.

您的脚本假定文件中的行适当长.如果你的文件不包含换行符,你将整个文件加载到$_的内存中,然后用拆分加倍内存加载,然后在你的散列中添加更多.这会对任何系统造成压力.

一个想法可能是使用空格“”作为输入记录分隔符.它将大致完成你已经使用split进行的操作,除了它将单独留下其他空白字符,并且不会像过时那样修剪多余的空白.例如:

$/ = " ";

while (<>) {

for my $word ( split ) { # avoid e.g. "foo\nbar" being considered one word

if (

(length($word) >= $min_len) &&

($word =~ /^[A-Z][A-Z\'-]+$/) &&

(index($word,"'") < 0 || allow_apostrophe($word))

) {

$dict{$word}++;

}

}

}

这将允许甚至很长的行以一口大小的块读取,假设您在单词之间(而不是制表符或换行符)之间有空格.

标签:linux,out-of-memory,perl

来源: https://codeday.me/bug/20190721/1494858.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值