Реализация ObjectIDGenerator

#c# #.net #optimization #xna #cross-platform

#c# #.net #оптимизация #xna #кроссплатформенный

Вопрос:

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

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

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

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

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

Комментарии:

1. Может помочь, если вы сможете опубликовать некоторый пример кода, который добавляет 20 000 объектов и сообщает о времени в консольном приложении, чтобы другие могли быстро поиграть с вашим кодом и опубликовать результаты.

Ответ №1:

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

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

Обновить

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

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

Вы можете сами увидеть исходный код с помощью инициативы Microsoft по совместному использованию исходного кода:

Комментарии:

1. ligos, спасибо миллион за ответ, я даже не знал, что исходный код доступен! Я собираюсь пойти посмотреть и посмотреть, не могу ли я сделать что-то подобное.

2. Вы также должны иметь возможность заглянуть за кулисы Dictionary<T, K> реализации; чтобы понять, почему это занимает больше времени. Общий исходный код — это хорошо хранимый секрет, о котором должны знать больше разработчиков .NET!

3. Удивительно! Я нашел реализацию, и она работала прямо из коробки (мне просто пришлось удалить некоторые материалы для отладки / контракта, которые не были доступны в сборках XBox). Действительно, спасибо! Это не первый случай, когда у меня отсутствуют реализации классов на XBox, и теперь я могу перейти прямо к источнику!

4. Я был бы немного осторожен, копируя исходный текст дословно. Могут возникнуть проблемы с лицензированием / роялти. Особенно, если вы собираетесь получать прибыль от своей игры XNA. Внимательно прочитайте лицензию в исходном коде Microsoft!