我想讀取和寫入Guids數組到AppFabric緩存。我的配置文件顯示它正在將此序列化到Xml,這意味着事情進展太慢。 A Guid[20000]
需要60 ms來添加到緩存中,而類似大小的int[80000]
需要10 ms。我認爲Guid數組肯定看起來像是內部某個字節數組。什麼是最快的方式來達到這個目標,同時儘可能地產生細小的絨毛?我知道我將在緩存中添加哪些內容,並且數據不會特別持久,因此我不關心序列化類信息。序列化Guid []快速二進制存儲在C#AppFabric
4
A
回答
4
我會如果串行化驚訝AppFabric緩存使用的其他任何東西都不是WCF的二進制編寫器,所以如果是這種情況(看起來像這樣),那麼區別就是用二進制格式處理數組。某些原始類型的數組有一個special node type,它允許它們以二進制格式非常有效地存儲。 int(和字節)是其中的一些類型。 Guid不是(我不知道團隊選擇什麼來決定什麼是「陣列類型」)。因此,以二進制格式序列化整數數組非常高效,但序列化Guid數組卻不是。
正如m0sa建議,你可以將它轉換爲byte [],你可能會看到一個很大的改進。我發現,雖然LINQ語法更清晰,但並不能爲您提供更傳統的for循環所帶來的巨大性能改進。我已經運行下面的代碼來比較序列化速度(我認爲它將映射到AF緩存),並且序列化爲byte [](即使Guid []到byte []之間的轉換)甚至比來自int []的那個。
public class StackOverflow_6346646
{
static void SerializeGuid()
{
Console.WriteLine("Serializing Guid[]");
var guids = new Guid[20000];
Random rndGen = new Random();
for (int i = 0; i < guids.Length; i++)
{
guids[i] = Guid.NewGuid();
}
MemoryStream ms = new MemoryStream();
Stopwatch watch = new Stopwatch();
DataContractSerializer dcs = new DataContractSerializer(guids.GetType());
XmlDictionaryWriter binaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ms);
watch.Start();
dcs.WriteObject(binaryWriter, guids);
binaryWriter.Flush();
watch.Stop();
Console.WriteLine("Serialized in {0}ms, total size = {1} bytes", watch.ElapsedMilliseconds, ms.Position);
}
static void SerializeInt()
{
Console.WriteLine("Serializing int[]");
var guids = new int[80000]; // new Guid[20000];
Random rndGen = new Random();
for (int i = 0; i < guids.Length; i++)
{
guids[i] = rndGen.Next(); // Guid.NewGuid();
}
MemoryStream ms = new MemoryStream();
Stopwatch watch = new Stopwatch();
DataContractSerializer dcs = new DataContractSerializer(guids.GetType());
XmlDictionaryWriter binaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ms);
watch.Start();
dcs.WriteObject(binaryWriter, guids);
binaryWriter.Flush();
watch.Stop();
Console.WriteLine("Serialized in {0}ms, total size = {1} bytes", watch.ElapsedMilliseconds, ms.Position);
}
static void SerializeGuidAsByteArray(bool useLinq)
{
Console.WriteLine("Serializing Guid[] as byte[], {0}", useLinq ? "using LINQ" : "not using LINQ");
var guids = new Guid[20000];
Random rndGen = new Random();
for (int i = 0; i < guids.Length; i++)
{
guids[i] = Guid.NewGuid();
}
MemoryStream ms = new MemoryStream();
Stopwatch watch = new Stopwatch();
DataContractSerializer dcs = new DataContractSerializer(typeof(byte[]));
XmlDictionaryWriter binaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ms);
watch.Start();
byte[] bytes;
if (useLinq)
{
bytes = guids.SelectMany(x => x.ToByteArray()).ToArray();
}
else
{
bytes = new byte[guids.Length * 16];
for (int i = 0; i < guids.Length; i++)
{
byte[] guidBytes = guids[i].ToByteArray();
Buffer.BlockCopy(guidBytes, 0, bytes, 16 * i, 16);
}
}
dcs.WriteObject(binaryWriter, bytes);
binaryWriter.Flush();
watch.Stop();
Console.WriteLine("Serialized in {0}ms, total size = {1} bytes", watch.ElapsedMilliseconds, ms.Position);
}
public static void Test()
{
SerializeGuid();
SerializeInt();
SerializeGuidAsByteArray(true);
SerializeGuidAsByteArray(false);
}
}
2
使用Guid。 ToByteArray()
Guid[] yourArray = ...;
byte[][] serializedArray = yourArray.Select(x => x.ToByteArray()).ToArray();
你甚至可以將其序列化到1個維陣列中,由於的Guid字節數組的長度是已知的(16):
byte[] serializedArray = yourArray.SelectMany(x => x.ToByteArray()).ToArray();
相關問題
- 1. Silverlight二進制/更快序列化
- 2. 爲什麼二進制序列化比xml序列化更快?
- 3. 使用C#進行二進制Plist序列化/反序列化#
- 4. 快速排序二進制數組
- 5. Appfabric緩存 - 序列化
- 6. C#對象二進制序列化
- 7. C#的DataTable二進制序列化
- 8. C#,無法序列化爲二進制
- 9. C#二進制序列化錯誤
- 10. 二進制序列化/反序列化
- 11. 序列化 - 反序列化(二進制)
- 12. 存儲在應用程序二進制
- 13. 用於Windows Phone 7的快速而全面的二進制序列化框架
- 14. C# - XML反序列化與二進制反序列化與二元期權+ Deflate
- 15. 如何爲快速二進制存在/不存在的查找存儲文本校驗和?
- 16. 二進制序列化到列表
- 17. 列表的二進制(反)序列化
- 18. 快速傳輸二進制文件
- 19. 快速序列化 - Android
- 20. 在C程序中存儲「二進制」數據類型
- 21. AppFabric緩存和序列化IQueryable對象
- 22. 在xml中存儲C++二進制輸出
- 23. 反序列化Guid c的列表#
- 24. 排除父對象上的二進制序列化在C#
- 25. C++ - 在小端中序列化雙向二進制文件
- 26. 在python中反序列化objective-c二進制NSMutableArray
- 27. 純C/C++中的二進制序列化
- 28. 快速十六進制到二進制轉換方法.net
- 29. 二進制序列化與使用WCF
- 30. VB.Net二進制序列化異常