Как быстрее перевести два байта в переменную типа unsigned short?

Рейтинг: 1Ответов: 1Опубликовано: 31.05.2011

Есть массив unsigned char B[2], необходимо перевести эти два байта в переменную типа unsigned short, какой из описанных ниже алгоритмов справится с этим быстрей!?

  1. unsigned short A=B[0]+B[1]*255;
  2. unsigned short A; CopyMemory (&A,B,2);

И второй дополнительный вопрос - если потребуется преобразовать 8 байт в тип double, какой алгоритм победит?

Ответы

▲ 4Принят
unsigned short A=B[0]+B[1]*255;

Сводится по сути к B[0]+B[1]<<8; Т.е. основное - две операции: сложение+сдвиг. И с умножением ошиблись - нужно умножать на 0x100, т.е. 256. Если переменная A сильно нужна - добавить пересылки в память. По факту - скорее всего переменная A оптимизируется и значение возьмется из регистра процессора.

unsigned short A; CopyMemory (&A,B,2);

Вызов ф-ции. Итого - организация стека (push/pop, настройка регистров, передача параметров), код самой ф-ции. Если функция встраиваемая - уже лучше, но по скорости все равно будет хуже, чем сложение+сдвиг, т.к. имеется работа с памятью. Оптимизировать не удастся.

uint16_t A = *(uint16_t*)&B[0];

и клоны. Всего лишь две пересылки (память -> регистр, регистр -> память). В лучшем случае соптимизируется и значение A далее опять же возьмется из регистра. Т.е. по факту - одно чтение из памяти. И никаких записей в память.

Вообще на самом деле надо брать и смотреть ассемблерный листинг. Сейчас все компиляторы оптимизирующие. И просто грубо преобразовывать однозначно одну инструкцию языка в одну или несколько инструкций процессора не будут. А будут подгадывать максимально эффективный вариант по одному из критериев. Их на самом деле два: скорость и размер. И для каждого процессора правила оптимизации свои.

Касательно double:

double A = *(double*)&B[0];

Но с даблом я бы поостерегся. Дело в том, что целые числа хранятся как целые, поразрядно. Каждый байт последовательно друг за другом. И запись

unsigned short A=B[0]+B[1]*256;
unsigned long  C=B[0]+B[1]<<8+B[2]<<16+B[3]<<24;

работает. А внутреннее представление double существенно сложнее. Мантисса, экспонента, знаки... Фу. бр. И просто выдрать из double определенные разряды сложнее.