Реализация ObjectIDGenerator - PullRequest
       10

Реализация ObjectIDGenerator

1 голос
/ 17 октября 2011

Я пытался использовать ObjectIDGenerator в C # для генерации уникального идентификатора во время сериализации, однако этот класс недоступен в платформах XBox360 или Windows Phone 7 .NET (они используют компактную версию .NET). Я реализовал версию с использованием словаря Object для Int64 и смог получить полностью рабочую версию, однако производительность неудовлетворительная. Я сериализирую порядка десятков тысяч объектов, и в настоящее время это самое большое узкое место в производительности сохранения / загрузки. При использовании фактической реализации .NET на ПК для сериализации около 20 000 объектов требуется около 0,3 секунды. Используя мою реализацию, это занимает около 6 секунд.

В профилировании я обнаружил, что в словарь были включены .TryGetValue и .Add (это имеет смысл, так как это как индексирование, так и добавление в хэш-карту). Что еще более важно, оператор виртуального равенства вызывался вместо простого сравнения ссылок, поэтому я реализовал IEqualityComparer, который использовал только ReferenceEquals (это привело к увеличению скорости).

Кто-нибудь имеет представление о лучшей реализации ObjectIDGenerator? Спасибо за вашу помощь!

Моя реализация: http://pastebin.com/H1skZwNK

[Изменить] Еще одно замечание: результаты профилирования говорят о том, что сравнение объектов / ReferenceEquals по-прежнему является узким местом с количеством посещений 43 000 000. Мне интересно, есть ли способ хранить данные вдоль этого объекта без необходимости искать его в хэш-карте ...

1 Ответ

4 голосов
/ 17 октября 2011

Можно ли использовать свойство / дескриптор Int32 Id для каждого объекта, а не Object? Это может помочь вещам. Похоже, вы в любом случае присваиваете номер типа Id каждому объекту, только тогда вы смотрите вверх на основе ссылки на объект вместо идентификатора. Можете ли вы сохранить идентификатор объекта (ваш Int64) внутри каждого объекта и превратить ваш словарь в Dictionary<Int64, Object> вместо этого?

Возможно, вы также захотите узнать, работают ли SortedDictionary<TKey, TValue> или SortedList<TKey, TValue> лучше или хуже. Но если ваше основное узкое место в вашем IEqualityComparer, это не очень поможет.

UPDATE

После просмотра API класса ObjectIDGenerator я понимаю, почему вы не можете делать то, что я советовал сначала; вы создаете идентификаторы!

ObjectIDGenerator, кажется, вручную реализует свою собственную хеш-таблицу (она выделяет object[] и параллель long[] и изменяет их размер при добавлении объектов). Он также использует RuntimeHelpers.GetHashCode(Object) для вычисления своего хэша, а не IEqualityComparer, который может значительно повысить вашу производительность, поскольку он всегда вызывает Object.GetHashCode() и не выполняет виртуальный вызов для производного типа (или вызов интерфейса в вашем случае с IEqualityComparer).

Вы можете сами увидеть источник с помощью Инициативы Microsoft Shared Source :

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...