нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж.
и тут у меня несколько вопросов:
1. какие типы нужно преобразовывать? все фундаментальные? а как быть со строками?
2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?
3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?
наверное еще вопросы возникнут походу.
благодарен.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж. X>и тут у меня несколько вопросов: X>1. какие типы нужно преобразовывать? все фундаментальные? а как быть со строками?
Целые, вещественные — да. Строки — юникод в utf-16, utf-32 и прочие wide char.
Ещё есть хохмы с UUID — часть полей переворачивается, часть — нет.
X>2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?
Как постановишь, так и будет. Это же решение уровня спецификации.
X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?
Здравствуйте, niXman, Вы писали:
X>нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж.
X>1. какие типы нужно преобразовывать? все фундаментальные? а как быть со строками?
utf8 одинаково записывается вне зависимости от порядка байт. Для utf32 на самом деле есть два представления: utf32le и utf32be; у utf16 аналогично.
X>2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?
Обычно удобно чтобы библиотека отдавала данные в нативном формате. Не всегда так бывает, конечно, но вот уж библиотека сериализации просто обязана так делать. Какая-же это сериализация, если клиент должен заботится о порядке байт?
Или ты об порядке в котором хранить данные вне использующей библиотеке программы? Тут уж выбирай сам — всё равно разница не велика. Вполне нормально позаботится и сделать так, чтобы большинству клиентов не пришлось преобразовывать порядок.
X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?
Да не больше там проблем чем с целыми числами. Бывает, например, что endiannes для вещественных и для целых чисел не обязательно совпадают на одной машине. Но это такой же исторический курьёз, как и не little/big представления порядка байт.
X> при конвертировании порядка бит
И почему ты упоминаешь про биты? Обычно endiannes — это про байты.
Если у тебя порядок бит не совпадает, то это скорее аппаратная проблема :) То есть исправить, конечно, можно. Но обычно такая ситуация не встречается.
Здравствуйте, netch80, Вы писали:
N>Ещё есть хохмы с UUID — часть полей переворачивается, часть — нет.
а это что за тип такой?
N>Как постановишь, так и будет. Это же решение уровня спецификации.
я просто подумал, что, к примеру, если у моего сервера 80% — пользователей с x86 архитектурой, то, чтоб не нагружать сервер преобразованиями — отдавать данные в x86 порядке бит. остальные же 20% пользователей будут на своей стороне выполнять преобразования.
или это как-то по другому делается?
но, думается мне, отдавать данные в два потока одновременно — плохая идея.
N>Она такая же, как с целыми. Например: N>
Здравствуйте, watchmaker, Вы писали:
W>Или ты об порядке в котором хранить данные вне использующей библиотеке программы?
выше уже объяснил.
W>Вполне нормально позаботится и сделать так, чтобы большинству клиентов не пришлось преобразовывать порядок.
я тоже так подумал.
W>Да не больше там проблем чем с целыми числами. Бывает, например, что endiannes для вещественных и для целых чисел не обязательно совпадают на одной машине. Но это такой же исторический курьёз, как и не little/big представления порядка байт.
с этим вроде понял.
W>И почему ты упоминаешь про биты? Обычно endiannes — это про байты.
да? говорю же — в сабже профан
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?
Посмотри на postgresql C connector library (она же pqlib), там как раз все эти грабли заботливо собраны с их OID (OIDTYPES).
Здравствуйте, SkyDance, Вы писали:
SD>Посмотри на postgresql C connector library (она же pqlib), там как раз все эти грабли заботливо собраны с их OID (OIDTYPES).
что я там должен посмотреть?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, SkyDance, Вы писали:
SD>На типы, которые требуют изменения endian-ness, и на их float/double конверсии.
это равносильно предложению "посмотрите исходники в интернетах"
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж.
Если нет требований обеспечить максимальное быстродействие, то сериализуй в XML в кодировке utf-8.
Плюсы:
1. Нет проблем с порядком байт
2. Легко изменять и дополнять формат не ломая совместимости
3. Можно просто открыть блокнотом, чтобы посмотреть или поправить значения
Здравствуйте, niXman, Вы писали:
X>я просто подумал, что, к примеру, если у моего сервера 80% — пользователей с x86 архитектурой, то, чтоб не нагружать сервер преобразованиями — отдавать данные в x86 порядке бит. остальные же 20% пользователей будут на своей стороне выполнять преобразования. X>или это как-то по другому делается?
Существует понятие "сетевой порядок байт". Это big-endian. Его и используй. Для преобразования есть функции htons() — преобразование из хостового в сетевой порядок байт для uin16_t и ntohs() — обратное преобразование. А так-же есть htonl()/ntohl() — преобразование для uint32_t.
Здравствуйте, niXman, Вы писали:
X>нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж.
Неверная формулировка — залог неуспеха.
Мне почему-то кажется, что вам нужно не "преобразовывать сабж", а обеспечить единый формат сериализованных данных для платформ с различным порядком байт. Ы?
X>и тут у меня несколько вопросов: X>1. какие типы нужно преобразовывать? все фундаментальные? а как быть со строками?
Ответ очевиден: преобразовывать нужно те данные, которые в разных архитектурах хранятся по-разному.
К примеру, преобразовывать char, скорее всего, не придется (он и так однобайтовый). А вот short, int и long придется переконвертировать (например, функциями htons, htonl).
Со строками нужно быть предельно осторожным и учитывать формат сериализации. Если перед данными строки вы пишете ее длину — нужно проследить, чтобы длина писалась в едином формате. Данные строки, скорее всего, конвертировать не нужно (если строка в байтовой кодировке типа ASCII или UTF-8). Если строка в юникоде, то нужно следить, чтобы символы юникода писались в правильном формате.
X>2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?
Конвертация данных через стандартные функции htons/htonl — операция весьма быстрая. На интеловских процах она сводится к одной-единственной дополнительной операции (проверено на GCC с оптимизацией -O2). На биг-ендиан системах, соответственно, эти функции вообще ни в какой код не транслируются.
Так что я бы не парился и сериализовал данные в сетевом формате байт (т.е., биг-ендиан).
X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?
Есть мнение, что флоаты лучше вообще не писать в бинарном формате, если хочется переносимости данных. Форматы флоатов, несмотря на существование стандартов, могут быть разными в зависимости от используемого железа и даже опций компиляции. Впрочем, на практике все не так уж и плохо, и флоаты таки активно пишут и читают в бинарном виде. Правда, для "переворота" байт придется, скорее всего, самописный лисапет нарисовать.
А вот порядок битов в структурах на биг- и литтл-ендиан системах действительно может быть разным. Имеется в виду не абстракция ("где в байте самый старший бит"), а конкретика: в каком порядке компилятор отводит биты для структур с битовыми полями. Например, для такой вот структурки:
struct a {
int m: 1,
int n: 2,
int p: 3
};
ГЦЦ под Интелом отведет биты, начиная с LSB: 00pppnnm (два старших бита нулевые — паддинг).
Под биг-ендиан системой (например, SPARC), компилятор начнет отводить биты, начиная с MSB: mnnppp00.
Заметим, что различается только место расположения полей в байтах; биты внутри полей всегда идут в "нормальном" порядке. То есть, скажем, если в p записать число 3 (011 в бинарном виде), то в байте оно будет выглядеть так:
00011nnm (интел)
mnn01100 (спарк)
Соответственно, при записи-чтении битовых полей нужно предусмотреть их преобразование в единый формат. Сделать это на уровне библиотеки сериализации можно, но муторно. Проще вообще отказаться от сериализации структур с битовыми полями.
Здравствуйте, niXman, Вы писали:
X>1. какие типы нужно преобразовывать? все фундаментальные?
Когда я решал такую задачу, то поддерживать все типы оказалось довольно проблематично, в том числе и из-за разной длины в байтах на разных платформах. Поэтому я упростил задачу сведя все типы к нескольким основным: целое 8 байт, целое со знаком 8 байт, unix time 8 байт, double IEEE 754 8 байт, строка.
X>а как быть со строками?
Длина в начале в байтах, затем текст в utf-8.
X>2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?
Да, нормальный подход.
X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?
Храни в IEEE 754 с известным тебе порядом байт, если на платформе формат отличается — конвертируй.
Здравствуйте, Хреннос, Вы писали:
Х>Конвертация данных через стандартные функции htons/htonl — операция весьма быстрая. На интеловских процах она сводится к одной-единственной дополнительной операции (проверено на GCC с оптимизацией -O2). На биг-ендиан системах, соответственно, эти функции вообще ни в какой код не транслируются. Х>Так что я бы не парился и сериализовал данные в сетевом формате байт (т.е., биг-ендиан).
т.е. предлагаете конвертировать по умолчанию?
Х>Проще вообще отказаться от сериализации структур с битовыми полями.
у нас это сделано проще — каждый мембер такой структуры сериализуется как полный тип мембера.
т.е. для вашего примера сериализация произведется для такого типа:
struct a {
int m;
int n;
int p;
};
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, MTD, Вы писали:
MTD>Когда я решал такую задачу, то поддерживать все типы оказалось довольно проблематично, в том числе и из-за разной длины в байтах на разных платформах. Поэтому я упростил задачу сведя все типы к нескольким основным: целое 8 байт, целое со знаком 8 байт, unix time 8 байт, double IEEE 754 8 байт, строка.
Кстати да, о различных размерах типов я совсем забыл.
X>>а как быть со строками?
MTD>Длина в начале в байтах, затем текст в utf-8.
XDR — сериализует данные в биг-ендиан, весьма жирный (в том смысле, что любая запись занимает не менее 4 байт, и любая запись кратна четырем байтам). Это несет в себе нехилый оверхед для коротких типов (символов, булевых переменных, коротких строк).
ProtoBuf — разработан в недрах гугля, весьма компактен, данные сериализуются в формате литтл-ендиан.
Здравствуйте, MTD, Вы писали:
MTD>Храни в IEEE 754
где-то я уже видел эту аббревиатуру
а что значит "храни"? если сериализация происходит на x86 машине, то флоаты в каком формате?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, Хреннос, Вы писали:
Х>>Конвертация данных через стандартные функции htons/htonl — операция весьма быстрая. На интеловских процах она сводится к одной-единственной дополнительной операции (проверено на GCC с оптимизацией -O2). На биг-ендиан системах, соответственно, эти функции вообще ни в какой код не транслируются. Х>>Так что я бы не парился и сериализовал данные в сетевом формате байт (т.е., биг-ендиан). X>т.е. предлагаете конвертировать по умолчанию?
Вам решать.
Я всего лишь подчеркнул, что конвертация в сетевой формат данных на интеловских процессорах практически бесплатна: одна дополнительная команда процессора выполняется очень быстро. Какую-то разницу нам удалось обнаружить только в тестах, гоняющих миллиарды преобразований структур (и то различия был в районе 1-2%); в реальном коде влияние конвертации неощутимо.
Кстати, в наших тестах структуры были довольно большими и с битовыми полями внутри (кадры специфических сетевых протоколов).
Х>>Проще вообще отказаться от сериализации структур с битовыми полями. X>у нас это сделано проще — каждый мембер такой структуры сериализуется как полный тип мембера.