Прежде всего, используйте
#include <arpa/inet.h>
little_endian = ntohs(big_endian);
Это скомпилирует в оптимальный код на любой системе, которую вы используете, и даже сработает, если вам случится перенести ваш код на платформу с прямым порядком байтов.
Однако это не решит проблему с производительностью, так как я считаю, что вы ее неправильно определили.Первое правило микрооптимизации Nemo: «Математика - это быстро; память - медленно».
Итерации по большому блоку памяти и перестановка его байтов крайне недружественны для кеша.Обмен байтов - это один цикл;чтение или запись в память занимает сотни циклов, если она не попадет в кэш.
Так что не меняйте местами байты, пока вы не используете их .Мой личный любимый подход заключается в следующем:
class be_uint16_t {
public:
be_uint16_t() : be_val_(0) {
}
be_uint16_t(const uint16_t &val) : be_val_(htons(val)) {
}
operator uint16_t() const {
return ntohs(be_val_);
}
private:
uint16_t be_val_;
} __attribute__((packed));
Это определяет двухбайтовый класс, который представляет число с прямым порядком байтов в памяти.Он неявно приводится к и из uint16_t по мере необходимости.Так что приведите указатель вашей памяти к be_uint16 *
и просто обращайтесь к нему как к массиву;забудьте о замене байтов, потому что класс сделает это за вас:
const be_uint16_t *p = (be_uint16 *)my_block;
unsigned val = p[37]; // or whatever
Обратите внимание, что вы можете даже делать такие вещи:
be_uint16_t x = 12;
x = x + 1;
write(fd, &x, sizeof(x)); // writes 13 to file in big-endian form
Затраты на замену значения непосредственно передиспользование, по моему опыту, необнаружимо.Местность - это название игры ...