#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!