如果OverwriteList
修復它,那麼它表明我的詞典默認情況下有一些數據,也許通過構造函數或類似。如果確實來自構造函數,則可以使用[ProtoContract(SkipConstructor=true)]
來禁用它。
如果我誤解了上述內容,如果可能的話,它可能有助於說明一個可重現的例子。
關於ID,它們只需要在每種類型中都是唯一的,並且建議保持它們很小(由於標籤的「varint」編碼,小鍵比「大鍵」便宜)。
如果您想真正縮小尺寸,我實際上建議您也查看數據的內容。例如,你說這是15分鐘的讀數......好了,我猜偶爾有差距,但你可以做,例如:
Block (class)
Start Time (DateTime)
Values (float[])
,並有Block
爲15分鐘的值每連續一堆(這裏的假設是,以後每隔值爲15最後一個,否則開始一個新塊)。因此,您正在存儲多個Block
實例來代替單個字典。這樣做的優點:
- 更
DateTime
值存儲
- 你可以使用「打包」編碼彩車上,這意味着它不需要添加所有的中間標籤;您可以通過標記的數組/列表,(
[ProtoMember({key}, IsPacked = true)]
)做到這一點 - 提的是,它僅適用於一些基本數據類型(沒有子對象)
相結合,這兩個調整可能會產生顯著節省
如果數據有很多的字符串,你可以嘗試GZIP/DEFLATE。當然你也可以嘗試這些無論哪種方式,但沒有大量字符串數據,我會謹慎期待太多額外的壓縮。
作爲基於供應(CSV)的數據文件的更新,這裏沒有固有的問題處理的字典 - 如圖所示:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ProtoBuf;
class Program
{
static void Main()
{
var data = new Data
{
Points =
{
{new DateTime(2009,09,1,0,0,0), 11.04F},
{new DateTime(2009,09,1,0,15,0), 11.04F},
{new DateTime(2009,09,1,0,30,0), 11.01F},
{new DateTime(2009,09,1,0,45,0), 11.01F},
{new DateTime(2009,09,1,1,0,0), 11F},
{new DateTime(2009,09,1,1,15,0), 10.98F},
{new DateTime(2009,09,1,1,30,0), 10.98F},
{new DateTime(2009,09,1,1,45,0), 10.92F},
{new DateTime(2009,09,1,2,00,0), 10.09F},
}
};
var ms = new MemoryStream();
Serializer.Serialize(ms, data);
ms.Position = 0;
var clone =Serializer.Deserialize<Data>(ms);
Console.WriteLine("{0} points:", clone.Points.Count);
foreach(var pair in clone.Points.OrderBy(x => x.Key))
{
float orig;
data.Points.TryGetValue(pair.Key, out orig);
Console.WriteLine("{0}: {1}", pair.Key, pair.Value == orig ? "correct" : "FAIL");
}
}
}
[ProtoContract]
class Data
{
private readonly Dictionary<DateTime, float> points = new Dictionary<DateTime, float>();
[ProtoMember(1)]
public Dictionary<DateTime, float> Points { get { return points; } }
}
喜;我已經在SensorState簡單的介紹一下,但它不是在「最小」的狀態下,其實我可以跳和複製任何東西(我嘗試添加越來越多的文件得到它來編譯,但沒有成功)。我在下面添加了一個*最小*示例(處理提供的數據),顯示沒有問題。你能通過提供一個最小*工作,可重現*的例子來幫助你,幫助你解決問題嗎? –