Сообщение Re[4]: Опциональные типы от 23.02.2017 4:01
Изменено 23.02.2017 5:00 vdimas
Re[4]: Опциональные типы
Здравствуйте, meadow_meal, Вы писали:
_>Так предложи альтернативу.
Если речь об IDL, то проблемно-ориентированное кодирование всей твоей матрешки идёт вот так:
Если разновидность IDL с автоопределением типа дискриминанта, то будет даже проще:
(не надо явно вводить `enum ClanUpdate`)
Итого, для случая выхода из клана тоже достаточно одного байта, а не два, как у тебя сейчас.
Но можно еще проще.
Считаем, что "игрок больше не состоит в клане" — это тоже клан такой. Эдакий клан бесклановых игроков.
Выдели для него некий отдельный ID.
И далее можно унифицировано обновлять поля в плоском сообщении без геммороя со вложенными Nullable в другие Nullable.
_>Задача: имеется сущность Xxx, содержащая следующие свойства:
Задача тривиальная.
_>Решение в лоб:
_>
_>и если T это какой-нибудь Optional<int>, то так тому и быть. Вот здесь и образуется Optional<Optional<int>>.
А вот решение так себе.
Ты в сетку как передаёшь?
По байту на признак наличия каждого поля? Если брать IDL, то меньше байта не выйдет, верно? А если не проконтроллировать размер дискриминанта в union, то может легко быть и 2 байта и 4 байта. ))
В общем, использовать IDL в 2017-м (CORBA IDL небось?) — это вообще признак оторванности от реальности.
А полей сколько? Предположим, что у тебя 30 полей, а в среднем за раз передаются 2-3 поля?
И ты на каждое обновление пробегаешься по всем 30-ти полям, что ле, вот в этой манере:
Очевидно же, что стратегий упаковки обновлений может быть несколько.
Когда полей пересылается мало, то можно применить альтернативную кодировку — вначале прогнать номера полей (тут 5 бит на номер хватит), а потом их значения.
Когда полей посылается много, то можно вначале прогнать битовую маску. Сетевые драйвера баз данных, кста, зачастую делают точно так же: для каждой передаваемой записи, если в ней встречаются Nullable-поля, передаётся сначала битовая маску. И да, в этой битовой маске участвуют только Nullable поля. Например, если полей 16, но Nullable из них всего два, то обе стороны знают, что маску будет выделен 1 байт в сообщении.
Ну или можно взять какой-нить ASN.1 с хорошим профилём упаковки.
Но можно и самому набросать сериализатор. А еще лучше самому набросать утилиту генерации сериализатора по метаинформации, раз уж речь о дотнете, благо по состоянию на 2017-й год инфраструктура развита сильно (можно брать BLToolkit как маппер), там трудоемкости, скорее всего, будет меньше, чем возни с сопряжением c каким-нить IDL-фреймворком.
Через BLToolkit можно сделать так, чтобы код обновления полей вообще ручками писать не надо было.
_>Так предложи альтернативу.
Если речь об IDL, то проблемно-ориентированное кодирование всей твоей матрешки идёт вот так:
enum ClanUpdate { NoUpdate, EnterClan, ExitClan };
union ClanEvent switch (ClanUpdate) {
case NoUpdate: ;
case EnterClan: int ClanId;
case ExitClan: ;
};
Если разновидность IDL с автоопределением типа дискриминанта, то будет даже проще:
union ClanEvent {
case NoUpdate: ;
case EnterClan: int ClanId;
case ExitClan: ;
};
(не надо явно вводить `enum ClanUpdate`)
Итого, для случая выхода из клана тоже достаточно одного байта, а не два, как у тебя сейчас.
Но можно еще проще.
Считаем, что "игрок больше не состоит в клане" — это тоже клан такой. Эдакий клан бесклановых игроков.
Выдели для него некий отдельный ID.
И далее можно унифицировано обновлять поля в плоском сообщении без геммороя со вложенными Nullable в другие Nullable.
_>Задача: имеется сущность Xxx, содержащая следующие свойства:
Задача тривиальная.
_>Решение в лоб:
_>
_>record XxxUpdate
_>{
_> Optional<T1> value1;
_> Optional<T2> value2;
_> ...
_>}
_>
_>и если T это какой-нибудь Optional<int>, то так тому и быть. Вот здесь и образуется Optional<Optional<int>>.
А вот решение так себе.
Ты в сетку как передаёшь?
По байту на признак наличия каждого поля? Если брать IDL, то меньше байта не выйдет, верно? А если не проконтроллировать размер дискриминанта в union, то может легко быть и 2 байта и 4 байта. ))
В общем, использовать IDL в 2017-м (CORBA IDL небось?) — это вообще признак оторванности от реальности.
А полей сколько? Предположим, что у тебя 30 полей, а в среднем за раз передаются 2-3 поля?
И ты на каждое обновление пробегаешься по всем 30-ти полям, что ле, вот в этой манере:
void Update(XxxUpdate update)
{
if (update.Field1.HasValue)
this.Field1 = update.Field1.Value;
if (update.Field2.HasValue)
this.Field2 = update.Field2.Value;
...
Очевидно же, что стратегий упаковки обновлений может быть несколько.
Когда полей пересылается мало, то можно применить альтернативную кодировку — вначале прогнать номера полей (тут 5 бит на номер хватит), а потом их значения.
Когда полей посылается много, то можно вначале прогнать битовую маску. Сетевые драйвера баз данных, кста, зачастую делают точно так же: для каждой передаваемой записи, если в ней встречаются Nullable-поля, передаётся сначала битовая маску. И да, в этой битовой маске участвуют только Nullable поля. Например, если полей 16, но Nullable из них всего два, то обе стороны знают, что маску будет выделен 1 байт в сообщении.
Ну или можно взять какой-нить ASN.1 с хорошим профилём упаковки.
Но можно и самому набросать сериализатор. А еще лучше самому набросать утилиту генерации сериализатора по метаинформации, раз уж речь о дотнете, благо по состоянию на 2017-й год инфраструктура развита сильно (можно брать BLToolkit как маппер), там трудоемкости, скорее всего, будет меньше, чем возни с сопряжением c каким-нить IDL-фреймворком.
Через BLToolkit можно сделать так, чтобы код обновления полей вообще ручками писать не надо было.
Re[4]: Опциональные типы
Здравствуйте, meadow_meal, Вы писали:
_>Так предложи альтернативу.
Если речь об IDL, то проблемно-ориентированное кодирование всей твоей матрешки идёт вот так:
Если разновидность IDL с автоопределением типа дискриминанта, то будет даже проще:
(не надо явно вводить `enum ClanUpdate`)
Итого, для случая выхода из клана тоже достаточно одного байта, а не два, как у тебя сейчас.
Но можно еще проще.
Считаем, что "игрок больше не состоит в клане" — это тоже клан такой. Эдакий клан бесклановых игроков.
Выдели для него некий отдельный ID.
И далее можно унифицировано обновлять поля в плоском сообщении без геммороя со вложенными Nullable в другие Nullable.
_>Задача: имеется сущность Xxx, содержащая следующие свойства:
Задача тривиальная.
_>Решение в лоб:
_>
_>и если T это какой-нибудь Optional<int>, то так тому и быть. Вот здесь и образуется Optional<Optional<int>>.
А вот решение так себе.
Ты в сетку как передаёшь?
По байту на признак наличия каждого поля? Если брать IDL, то меньше байта не выйдет, верно? А если не проконтроллировать размер дискриминанта в union, то может легко быть и 2 байта и 4 байта. ))
В общем, использовать IDL в 2017-м (CORBA IDL небось?) — это вообще признак оторванности от реальности.
А полей сколько? Предположим, что у тебя 30 полей, а в среднем за раз передаются 2-3 поля?
И ты на каждое обновление пробегаешься по всем 30-ти полям, что ле, вот в этой манере:
Очевидно же, что стратегий упаковки обновлений может быть несколько.
Когда полей пересылается мало, то можно применить альтернативную кодировку — вначале прогнать номера полей (тут 5 бит на номер хватит), а потом их значения.
Когда полей посылается много, то можно вначале прогнать битовую маску. Сетевые драйвера баз данных, кста, зачастую делают точно так же: для каждой передаваемой записи, если в ней встречаются Nullable-поля, передаётся сначала битовая маска. И да, в этой битовой маске участвуют только Nullable поля. Например, если полей 16, но Nullable из них всего два, то обе стороны знают, что на маску будет выделен 1 байт в потоке.
Ну или можно взять какой-нить ASN.1 с хорошим профилём упаковки.
Но можно и самому набросать сериализатор. А еще лучше самому набросать утилиту генерации сериализатора по метаинформации, раз уж речь о дотнете, благо по состоянию на 2017-й год инфраструктура развита сильно (можно брать BLToolkit как маппер), там трудоемкости, скорее всего, будет меньше, чем возни с сопряжением c каким-нить IDL-фреймворком.
Через BLToolkit можно сделать так, чтобы код обновления полей вообще ручками писать не надо было.
_>Так предложи альтернативу.
Если речь об IDL, то проблемно-ориентированное кодирование всей твоей матрешки идёт вот так:
enum ClanUpdate { NoUpdate, EnterClan, ExitClan };
union ClanEvent switch (ClanUpdate) {
case NoUpdate: ;
case EnterClan: int ClanId;
case ExitClan: ;
};
Если разновидность IDL с автоопределением типа дискриминанта, то будет даже проще:
union ClanEvent {
case NoUpdate: ;
case EnterClan: int ClanId;
case ExitClan: ;
};
(не надо явно вводить `enum ClanUpdate`)
Итого, для случая выхода из клана тоже достаточно одного байта, а не два, как у тебя сейчас.
Но можно еще проще.
Считаем, что "игрок больше не состоит в клане" — это тоже клан такой. Эдакий клан бесклановых игроков.
Выдели для него некий отдельный ID.
И далее можно унифицировано обновлять поля в плоском сообщении без геммороя со вложенными Nullable в другие Nullable.
_>Задача: имеется сущность Xxx, содержащая следующие свойства:
Задача тривиальная.
_>Решение в лоб:
_>
_>record XxxUpdate
_>{
_> Optional<T1> value1;
_> Optional<T2> value2;
_> ...
_>}
_>
_>и если T это какой-нибудь Optional<int>, то так тому и быть. Вот здесь и образуется Optional<Optional<int>>.
А вот решение так себе.
Ты в сетку как передаёшь?
По байту на признак наличия каждого поля? Если брать IDL, то меньше байта не выйдет, верно? А если не проконтроллировать размер дискриминанта в union, то может легко быть и 2 байта и 4 байта. ))
В общем, использовать IDL в 2017-м (CORBA IDL небось?) — это вообще признак оторванности от реальности.
А полей сколько? Предположим, что у тебя 30 полей, а в среднем за раз передаются 2-3 поля?
И ты на каждое обновление пробегаешься по всем 30-ти полям, что ле, вот в этой манере:
void Update(XxxUpdate update)
{
if (update.Field1.HasValue)
this.Field1 = update.Field1.Value;
if (update.Field2.HasValue)
this.Field2 = update.Field2.Value;
...
Очевидно же, что стратегий упаковки обновлений может быть несколько.
Когда полей пересылается мало, то можно применить альтернативную кодировку — вначале прогнать номера полей (тут 5 бит на номер хватит), а потом их значения.
Когда полей посылается много, то можно вначале прогнать битовую маску. Сетевые драйвера баз данных, кста, зачастую делают точно так же: для каждой передаваемой записи, если в ней встречаются Nullable-поля, передаётся сначала битовая маска. И да, в этой битовой маске участвуют только Nullable поля. Например, если полей 16, но Nullable из них всего два, то обе стороны знают, что на маску будет выделен 1 байт в потоке.
Ну или можно взять какой-нить ASN.1 с хорошим профилём упаковки.
Но можно и самому набросать сериализатор. А еще лучше самому набросать утилиту генерации сериализатора по метаинформации, раз уж речь о дотнете, благо по состоянию на 2017-й год инфраструктура развита сильно (можно брать BLToolkit как маппер), там трудоемкости, скорее всего, будет меньше, чем возни с сопряжением c каким-нить IDL-фреймворком.
Через BLToolkit можно сделать так, чтобы код обновления полей вообще ручками писать не надо было.