2012-05-03 14 views
4

我有一個用Perl編寫的解析器,它解析固定長度記錄的文件。部分記錄由多個字符串組成(也是固定長度),僅由數字組成。字符串中的每個字符都被編碼爲數字,而不是ASCII字符。也就是說,如果我有字符串12345,它編碼爲01 02 03 04 05(而不是31 32 33 34 35)。解壓縮結合加入Perl的性能

我用解壓解析記錄,這個特定部分被解壓爲@array = unpack "C44", $s。然後我通過簡單的連接恢復所需的字符串,如$m = join("", @array)

我想知道如果這是一個最佳的解碼方式。文件相當大,數百萬條記錄,顯然我試圖查看是否可以優化。 Profiler顯示大部分時間都用於解析記錄(即讀取,寫入和其他東西不是問題),並且在解析大部分時間都是由這些連接取得的。我從其他來源記得,加入是非常有效的操作。任何想法,如果有可能加快代碼或已經是最佳的?也許有可能以某種聰明的方式避免這個中間數組,例如使用pack/unpack組合呢?

編輯:代碼示例

我嘗試優化看起來像這樣的代碼:

while (read(READ, $buf, $rec_l) == $rec_l) { 
     my @s = unpack "A24 C44 H8", $buf; 
     my $msisdn = substr $s[0], 0, 11; 
     my $address = join("", @s[4..14]); 
     my $imsi = join("", @s[25..39]); 
     my $ts = localtime(hex($s[45])); 
    } 

回答

0

在Perl與往常一樣,更快小於可讀:-)

join("", unpack("C44", $s)) 

我不相信這個改變會加快你的代碼。一切都取決於你多久調用一次連接函數來讀取整個文件。如果你在分塊工作,請嘗試增加它們的大小。如果你在解包和加入這個數組之間進行一些操作,嘗試將它們與一個映射操作對齊。如果您發佈源代碼,那麼識別瓶頸將更容易。

+0

增加了更多的問題代碼。 – MariusM

0

我一包/解包小白,但如何跳過通過改變像這樣的示例代碼加入:

my $m = unpack "H*", $s ; 

快速測試:

#!/usr/bin/perl 

use strict ; 
use Test::More tests => 1 ; 

is(unpack("H*", "\x12\x34\x56"),"123456"); 
6

未經測試(我會回來在我不太忙的時候回來和編輯),但是如果我已經正確地完成了所有的數學運算,並且速度更快,那麼這應該可行:

my ($msisdn, $address, $imsi, $ts) = 
    unpack "A11 x13 x3 a10 x10 a15 x5 N", $buf; 
$address |= "0" x 10; 
$imsi |= "0" x 15 
$ts = localtime($ts); 
+0

只需要小修改,除此之外這個工作正確。而且是我的兩倍。看着這個解壓我想知道我是如何設法想出這些連接:( – MariusM

+0

@MariusM如果你告訴我什麼是更正,我會很樂意編輯我的答案。 – hobbs

+1

'hex unpack'H8''是一個非常迂迴的做'解開'N''的方式。固定。 – ikegami