У меня есть API, получающий сообщения в виде структур в методе обратного вызова.
void OnReceive(ref T message)
. Этот метод получает эти объекты структуры по ссылке, чтобы избежать копирования. Я думаю обернуть этот API и выставить сообщения как наблюдаемые.
Учитывая, что я не могу сделать наблюдаемые ссылки на структуры и что структуры передаются/возвращаются путем создания копии этого решения
Observable<T> GetItems() //where T is struct
кажется довольно неоптимальным, и лучше продолжать использовать подход обратного вызова на всем протяжении. Есть ли лучший способ работы со структурами в библиотеке расширений Rx?
Смотрите здесь чтобы узнать больше об этом
@EnricoMassone, выбор использования структур был продиктован базовым API, который имеет дело с «неуправляемой» сериализацией более низкого уровня. Эти структуры имеют 20-30 полей, поэтому их размер слишком значителен, чтобы его игнорировать. Написание класса DTO кажется излишним.
Просто чтобы лучше понять вашу точку зрения, главная проблема, которую вы сейчас беспокоите, заключается в том, что, создавая наблюдаемую последовательность, вы в конечном итоге копируете экземпляры структуры? Правильно ли я понимаю?
@EnricoMassone, правильно. Проблема заключается в том, что каждый обратный вызов «выбрать», «где» и «подписаться» в конечном итоге приведет к многократному копированию структур для каждого сообщения.
Не могли бы вы просто обернуть тип значения в класс и передать наблюдаемому объекту класс? Примерно так: public class Ref<T> where T : struct { public T Value { get; init; } }
. Тогда у вас есть только одна копия, и после этого вы просто копируете ссылку.
@ddv - Пожалуйста, ответьте на мой комментарий выше.
да, я думаю, что это очень жизнеспособное решение здесь. Спасибо @Enigmativity
Только профилирование кода может подтвердить или опровергнуть любую гипотезу относительно производительности. Давая рекомендацию, используйте структуру только в том случае, если «Ее размер экземпляра меньше 16 байт» звучит так, как будто мы выполняем на процессоре 8085 и примерно в то же время. :) Возможно, вы захотите профилировать SomeClass<T>
и структуру T
, включая отслеживание побочных эффектов сборщика мусора. Могу поспорить, это все равно не будет иметь значения - учитывая, что вы все равно загружаете данные из API, что может рассчитывать на 99,99% производительности.
Вы можете просто обернуть тип значения в класс и передать наблюдаемому объекту класс.
Что-то вроде этого:
public class Ref<T> where T : struct { public T Value { get; init; } }
Насколько велики ваши структуры? Обычно структуры должны быть небольшими объектами с небольшим объемом данных. Вместо этого более крупные структуры данных следует моделировать как классы. Другими словами, мое первоначальное ощущение состоит в том, что вы обеспокоены преждевременной оптимизацией или вам следует изменить дизайн и вместо этого использовать класс.