Я храню простые временные ряды в следующем формате и ищу самый быстрый способ прочитать и проанализировать их, чтобы "процитировать" объекты:
DateTime, цена1, цена2
,
,
,
DateTime имеет следующий формат строки: ГГГГммдд ЧЧ: мм: сс: fff
цена1 и цена 2 - это строки чисел с 5 десятичными разрядами (1.40505, т.е.)
Я играл разными способами для хранения и чтения данных, а также играл с библиотекой protobuf-net. Файл, который был сериализован и содержал примерно 6 миллионов строк (raw csv сериализовался следующим образом:
объект TimeSeries, содержащий List<Blobs>
,
Blob-объект, содержащий объект Header и List<Quotes>
(один BLOB-объект содержит кавычки на один день)
Объект кавычки, содержащий DateTime, двойной px1 и двойной px2
Потребовалось около 47 секунд, чтобы прочитать (с диска) сериализованный двоичный файл и десериализовать его, что выглядело ужасно долго. В отличие от этого, я держал временные ряды в формате строки CSV, читал каждую строку в список, а затем анализировал каждую строку в DateTime dt, double px1, double px1, которые я вставил во вновь созданный объект Quote и добавил их в список.
Чтение заняло около 10 секунд (12 секунд при сжатии GZip -> создание файла размером примерно 1/9 размера.)
На первый взгляд мне кажется, что я либо неправильно работаю с протоколом protobuf-net, либо этот конкретный тип временных рядов плохо подходит для сериализации / десериализации.
Любые комментарии или помощь, особенно Марк, если вы прочитаете это, не могли бы вы присоединиться и добавить некоторые свои мысли? Мне трудно представить, что я получаю такие разные показатели производительности.
Некоторая информация: мне не нужен произвольный доступ к данным. Мне нужно только читать полные дни, поэтому хранение данных за один день в отдельном 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;
}