为什么protobuf-net反序列化器在我的代码中比流式传输csv慢得多

时间:2012-01-31 15:25:04

标签: c# serialization deserialization protobuf-net streamreader

我以下列格式存储简单的时间序列,并寻找最快的方式来阅读和解析它们"引用"对象:

DateTime,price1,price2 。 。 。 DateTime采用以下字符串格式:YYYYmmdd HH:mm:ss:fff price1和price 2是带小数点后5位的数字串(1.40505,即。)

我使用不同的方式来存储和读取数据,并玩弄了protobuf-net库。一个序列化并包含大约600万行的文件(以下列方式序列化原始csv:

TimeSeries对象,持有List<Blobs>, 持有标题对象的Blob对象和List<Quotes>(一个blob包含一天的引号) 引用对象持有DateTime,double px1和double px2

从序列化二进制文件中读取(从磁盘)大约需要47秒,并对其进行反序列化,这看起来非常长。相反,我将时间序列保存为csv字符串格式,将每行读入List,然后将每行解析为DateTime dt,double px1,double px1,我将其插入到新创建的Quote对象中并将其添加到List中。 这需要大约10秒钟才能读取(使用GZip压缩时间为12秒 - >使文件大小约为1/9。)

乍一看,我似乎错误地处理了protobuf-net功能,或者这种特定类型的时间序列不适合序列化/反序列化。

任何评论或帮助,特别是Marc,如果你读到这个,你可能会插入并添加你的一些想法吗?我发现很难想象我最终得到了如此不同的性能数字。

一些信息:我不需要随机访问数据。我只需要阅读整整一天,因此在一个单独的csv文件中存储一天的数据,这对我的目的是有意义的,我想。

任何想法可能是阅读此类数据的最快方式?我为简单化的语言道歉,我不是一个心灵的程序员。

这是我用于protobuf-net的示例对象:

[ProtoContract]
class TimeSeries
{
    [ProtoMember(1)]
    public Header Header { get; set; }
    [ProtoMember(2)]
    public List<DataBlob> DataBlobs { get; set; }
}

[ProtoContract]
class DataBlob
{
    [ProtoMember(1)]
    public Header Header { get; set; }
    [ProtoMember(2)]
    public List<Quote> Quotes { get; set; }
}

[ProtoContract]
class Header
{
    [ProtoMember(1)]
    public string SymbolID { get; set; }
    [ProtoMember(2)]
    public DateTime StartDateTime { get; set; }
    [ProtoMember(3)]
    public DateTime EndDateTime { get; set; }
}

[ProtoContract]
class Quote
{
    [ProtoMember(1)]
    public DateTime DateTime { get; set; }
    [ProtoMember(2)]
    public double BidPrice { get; set; }
    [ProtoMember(3)]
    public long AskPrice { get; set; } //Expressed as Spread to BidPrice
}

以下是用于序列化/反序列化的代码:

public static void SerializeAll(string fileNameWrite, List<Quote> QuoteList)
    {
        //Header
        Header Header = new Header();
        Header.SymbolID = SymbolID;
        Header.StartDateTime = StartDateTime;
        Header.EndDateTime = EndDateTime;

        //Blob
        List<DataBlob> DataBlobs = new List<DataBlob>();
        DataBlob DataBlob = new DataBlob();
        DataBlob.Header = Header;
        DataBlob.Quotes = QuoteList;
        DataBlobs.Add(DataBlob);

        //Create TimeSeries
        TimeSeries TimeSeries = new TimeSeries();
        TimeSeries.Header = Header;
        TimeSeries.DataBlobs = DataBlobs;

        using (var file = File.Create(fileNameWrite))
        {
            Serializer.Serialize(file, TimeSeries);
        }
    }

public static TimeSeries DeserializeAll(string fileNameBinRead)
    {
        TimeSeries TimeSeries;

        using (var file = File.OpenRead(fileNameBinRead))
        {
            TimeSeries = Serializer.Deserialize<TimeSeries>(file);
        }

        return TimeSeries;
    }

1 个答案:

答案 0 :(得分:4)

最快的方法是手动编码的二进制序列化器,特别是如果你改变pices ticks。这就是我所做的,虽然我的音量略有差异(每天6亿件,大约200,000个符号,其中一些是最重的)。我没有以任何需要从文本解析的方式存储任何内容。解析器是handcrafte,我使用分析器来优化它 - aos处理大小非常好(交易量低至1字节)。