2016-05-05 3 views
0

Я использую стандарт BinaryFormatter, чтобы сериализовать очень большой граф объектов с некоторыми сторонними объектами в миксе. Я пробовал других, таких как Protobuf/JSON/XML, и по той или иной причине все они потерпели неудачу. Данные по существу являются результатом сложного алгоритма AI и имеют большое количество удвоений в сильно вложенном дереве. Многие из них могут быть NaN.BinaryFormatter очень медленно с double.NaN

Похоже, что когда двойной является NaN, тогда BinaryFormatter терпит неудачу и обрабатывает его. Было бы неплохо, если бы оно правильно обработало.

Основная проблема описана в this link.

Есть ли работа, поэтому я могу напрямую заниматься NaN? Я могу сериализовать вещи напрямую, но это может быть большой проблемой.

Edit:

В одном из тяжелых преступников, которые наивная реализация Байеса код:

public double[][][] Distributions { get; private set; } 
public double[] Priors { get; private set; } 
+0

Должно ли это быть в данных как двойное, или вы также контролируете сторону чтения? Возможно, вы сможете просто перевести его в длинный и сохранить, что в зависимости от ваших требований. – harold

+0

'BinaryFormatter' сериализует поля, а не свойства, что несколько ограничивает ваши варианты. Можете ли вы дать представление о том, как выглядит ваш граф объектов? Значения NaN отображаются как поля во многих разных типах или просто для небольшого числа типов? – dbc

+0

Вы работаете в 32-битном или 64-битном режиме? См. [Здесь] (http://stackoverflow.com/questions/1953377) для проверки. Я спрашиваю, потому что [этот пост] (https://stackoverflow.com/questions/24331540) предполагает, что обработка значений NaN особенно медленна в 32-битном коде. – dbc

ответ

1

Все, что приходит на ум это.

Когда вы deserialize, он работает на потоке. Поток - это просто процессор для чтения байтов, и вы можете написать поток, который переписывает другой. Концептуально;

public NanToInfStreamReader: IStream 
{ 
    NanToInfStreamReader(IStream source) 
    { 
     ... 
    } 

    byte[] Read() 
    { 
     return ProtectAgainstNaN(source.Read()); 
    } 
} 

Таким образом, первая часть, чтобы написать поток украшения, как это, и поиск любого совпадения 64 битов, которые представляют собой Double.NaN. Подставьте их в свой поток для Double.Inf, скажем.

BinaryFormatter никогда не увидит Double.NaN, и проблема скорости не произойдет.

Однако теперь ваши данные заполнены + Inf везде, где у вас есть NaN, поэтому вам нужно вернуться через свои массивы и переписать их.

Это не очень хороший подход. Но похоже, что вы немного застряли, и это все, что я могу предложить.

+0

Интересный подход. Я никогда не думал об этом. – Telavian

+0

Если вы попытаетесь, попросите поток сообщить количество замещений. Подсчитайте количество исправлений, которые вы применяете после удаления десериализации. Если подсчеты не совпадают, вам необходимо работать с кодом исправления. Если то же самое, вы можете быть уверены, что это правильно. –