2008-11-10 61 views
8

我要存儲在一個壓縮格式下列元組的列表,我想知道哪種算法給我最好的壓縮算法? (見下文的最好的定義)

  • 最小壓縮大小
  • 最快德/壓縮
  • 最佳折衷(權衡曲線的 「拐點」)

我的數據是這樣的:

(<int>, <int>, <double>), 
(<int>, <int>, <double>), 
... 
(<int>, <int>, <double>) 

這兩個整數中的一個指的是一個時間點,並且很可能最終在一個列表中的數字彼此接近。另一個int代表一個抽象的id,並且值不太可能接近,儘管它們也不會完全隨機。雙重代表傳感器讀數,雖然這些值之間存在某種相關性,但它可能沒有多大用處。

回答

4

由於「時間」整數可以彼此接近,因此只嘗試存儲第一個和之後的值,然後將差值保存到int(delta編碼)之前。你也可以嘗試第二個int。

您可以嘗試的另一件事是重新組織從[int1,int2,double],[int1,int2,double] ...到[int1,int1 ...],[int2,int2 ...] ],[雙,雙...]。

要找出壓縮範圍,您可以將數據寫入文件並從Christian Martelock here下載壓縮機CCM。我發現它對這些數據收集表現非常好。它使用了相當快的算法context mixing。您也可以將其與其他壓縮機(如WinZIP)進行比較,或使用zLib之類的壓縮庫來查看是否值得付出努力。

2

如果我正確地閱讀這個問題,你只是想有效地存儲數據。很顯然,像壓縮XML這樣的簡單選項很簡單,但有更直接的二進制序列化方法。其中一個突出的問題是Google的protocol buffers

例如,在C#與protobuf-net,你可以簡單地創建一個類來保存數據:

[ProtoContract] 
public class Foo { 
    [ProtoMember(1)] 
    public int Value1 {get;set;} 
    [ProtoMember(2)] 
    public int Value2 {get;set;} 
    [ProtoMember(3)] 
    public double Value3 {get;set;} 
} 

然後,只需[德]序列化一個列表或富[]等,通過ProtoBuf.Serializer類。

我並不是說它會是相當於作爲滾動自己的空間效率,但它會相當接近。協議緩衝區規範可以很好地利用空間(例如,使用base-128作爲整數,這樣少量佔用較少的空間)。但是試一試很簡單,不必自己編寫所有的序列化代碼。

這種方法,以及易於實現,還具有易於從其他體系結構中使用的優點,因爲various languages有協議緩衝區實現。它還比普通的[de]壓縮(GZip/DEFLATE/etc)和/或基於xml的序列化要少得多。

+0

感謝您指出這一點,我使用pb序列化了一些東西,所以在我的上下文中它是一個很自然的選擇。你知道他們是否用較短的序列壓縮重複模式?如果不是,我也可以使用RTF規範。 ;-) – 2008-11-10 10:42:33

2

大多數壓縮算法對這些數據同樣不利。但是,有幾件事(「預處理」)可以在將數據提供給gzip或放縮算法之前提高數據的可壓縮性。請嘗試以下操作:

首先,如果可能,按升序對元組進行排序。先使用抽象標識,然後使用時間戳。假設你有多個來自同一個傳感器的讀數,類似的ID會放在一起。

接下來,如果定期採取措施,請將時間戳替換爲與先前時間戳的差(當然,除了傳感器的第一個元組外)。例如,如果所有措施都是在5分鐘間隔,兩個時間戳之間的增量通常接近300秒。因此時間戳字段將更加可壓縮,因爲大多數值是相等的。

然後,假設測量值在時間上穩定,將所有讀數替換爲相同傳感器先前讀數的增量。再次,大多數值將接近於零,因此更具可壓縮性。

另外,由於其內部表示形式,浮點值是非常糟糕的壓縮候選對象。嘗試將它們轉換爲整數。例如,溫度讀數最有可能不需要兩位以上的小數位。將值乘以100並四捨五入到最接近的整數。

2

以下是在大多數搜索引擎中使用的共同的方案:值的存儲三角洲和使用可變字節編碼方案,即,如果增量小於128編碼增量,它可以只用1個字節來編碼。有關詳細信息,請參閱Lucene和協議緩衝區中的vint。

這不會給你最好的壓縮比,但通常是編碼/解碼吞吐量最快的。

2

排序如已經提出的,然後將其存儲

(第一整數) (第二整數) (雙打)

轉置矩陣。然後壓縮

0

偉大的答案,備案,我要合併這些我upvoted進近,我終於用:

  1. 排序和重組的數據,這樣類似的數字是旁邊彼此,我。即排序ID,然後再通過時間戳和重新排列從(<int1>, <int2>, <double>), ...([<int1>, <int1> ...], [<int2>, <int2> ... ], [<double>, <double> ...])(如在時間戳所建議的增量編碼 schnaaderStephan Leclercq

  2. 使用(也許在其它值)由schnaaderididak

  3. 所建議
  4. 使用協議緩衝區序列化(我要在應用程序中使用反正他們,所以這不會依賴或添加任何東西)。感謝Marc Gravell指着我吧。