2016-08-03 64 views
2

現在我正在處理大文件,其大小大於(1.5 GB)。所以我用File::Map。當輸入大於2.1 GB腳本失敗,並顯示錯誤Use of uninitialized value $count in print at file.pl line 16.perl中標量變量是否有限制?

但是腳本運行2.1GB and below 2.1GB

我的腳本如下

use warnings; 
use strict; 
use File::Map 'map_file'; 
my $filename ="/root/Desktop/test_sequence/human_genome"; 

map_file (my $map,$filename); 

my $count; 

$count++ while ($map=~/>/g); 

print $count; #The file has only 14 `>` so result is 14. 

同時我試了一下沒有模塊。它也以相同的錯誤終止。

use warnings; 
use strict; 
my $filename ="/root/Desktop/test_sequence/human_genome"; 

open my $fh,"<",$filename or die "$!"; 

my $m = do{local $/; <$fh>}; 

my $count; 

$count++ while ($m=~/>/g); 

print $count; 

我不知道這裏有什麼問題?

+0

如果你正在做的是'>'計數 - 你真的需要將整個文件讀入內存? – Sobrique

+0

@Sobrique我正試圖在文件中找到重複。所以我想計算一個文件中的標題。然後我會繼續。 – mkHun

+0

要點是 - 你可能會找到一個'兩遍'的方法(閱讀文件尋找標記,再次讀取文件來處理它)更加高效,除非你需要做大量的數據集交叉引用。 – Sobrique

回答

-1

你已經在幾個地方一個打一個符號的32位整數限制

32位有符號值允許從0x1000_00000x7FFF_FFFF的值,即-2,147,483,648到2,147,483,647。因此,您的2.1GB限制

我不知道這是否是你的Perl構建的限制,或者如果它是File::Map部分

任意大小的文件,可以通過讀取一行在非常簡單的處理一時間,因爲在這裏你的目的似乎只是算一個Unicode GREATER-THAN SIGN字符數,你可以很容易地做這樣的

use strict; 
use warnings; 

use constant HUMAN_GENOME => '/root/Desktop/test_sequence/human_genome'; 

my $count = do { 

    open my $fh, '<', HUMAN_GENOME or die sprintf qq{Unable to open "%s": $!}, HUMAN_GENOME; 

    my $n = 0; 

    $n += tr/>// while <$fh>; 

    $n; 
}; 

print $count; 
+0

這就是我認爲的,但是從他的perl版本來看,這聽起來不太可能,而'File :: Map'確實可以處理大於4 GB的內容,所以它確實有點神祕。一個緩慢的工作版本比一個快速破碎的版本更好,但是通過'File :: Map'獲得5.6 GB的5 GB的性能足以讓我們繼續嘗試一下;) – mbethke

+0

好吧我會咬「*聽起來不太可能」* 。爲什麼?那麼影響你判斷的Perl代碼是什麼呢? – Borodin

+0

*「和'File :: Map'絕對可以處理大於4 GB的數據*」如果您有證據,請顯示您的代碼以便驗證。 – Borodin

0

問題的確是最大的標量大小。理論上,它可以在32位perl上增加4 GB,但由於地址空間限制在容納操作系統之類的地方,因此2-3.5 GB通常是真正的限制。使用64位操作系統和Perl它應該可以工作。

See this answer的一些細節。

編輯:正常工作在這裏,Perl 5.22.2在Fedora上,x86_64的Linux的線程多:

$ dd if=/dev/zero of=zero bs=1M count=5000 
5000+0 records in 
5000+0 records out 
5242880000 bytes (5.2 GB) copied, 34.8694 s, 150 MB/s 
$ perl -e 'sub wat{open my $fh, ">>zero" or die $!; 
    seek($fh,shift,0); syswrite($fh, ">");} 
    wat(1000); 
    wat(100_000_000); 
    wat(4_500_000_000);' 
$ time perl map.pl 
3 
real 0m5.638s 
user 0m3.921s 
sys  0m1.717s 
+0

我正在使用64位centOS 7,32 GB RAM。好的,File :: Map呢?從我的理解,這與文件直接鏈接。那麼爲什麼這也無法工作? – mkHun

+2

'perl -v'說什麼? – Sobrique

+0

@Sobrique它顯示'這是爲x86_64-linux-thread-multi構建的perl 5,版本16,subversion 3(v5.16.3) (有29個註冊補丁,..' – mkHun