воскресенье, 1 апреля 2012 г.

быстрое ппреобразование float в int

Давно не писал. Решил написать возможно полезную штуку. Это не мое, подсмотрел в чужих исходниках.
Собственно задача - быстро преобразовать float в int. Не знаю - имеет ли оно практическую ценность, но тем не менее данный способ по тестам показал что работает в 1/4-1/3 быстрее стандартных способов.
Вот функция:
typedef union
{
      int i;
      float f;
} INT_OR_FLOAT;
int FloatToInt(const float& _value)
{
      INT_OR_FLOAT n;
      INT_OR_FLOAT bias;

      if(_value > 0.0f)
            bias.i = (23 + 127) << 23;
      else
            bias.i = ((23 + 127) << 23) + (1 << 22);

      n.f = _value;

      n.f += bias.f;
      n.i -= bias.i;

      return n.i;
}
Я протестировал данный метод вместе с преобразованием в C стиле ( (int)float ) и используя static_cast. Внимание, тестировал в релизе. В дебаге, наша функция работает ужастно (проигрыш почти в 10 раз!!!!), поэтому учитывайте этот момент - выигрыш будет только в релизе (если вы сами настроили релиз в компиляторе, не забудьте протестировать)

Тестирование класса FastFloat

тестирование преобразования float в int

(int) (1 000 000): time 7 ms
static_cast (1 000 000): time 5 ms
FloatToInt (1 000 000): time 4 ms
Для продолжения нажмите любую клавишу . . .

тестирование преобразования float в int

(int) (1 000 000): time 4 ms
static_cast (1 000 000): time 5 ms
FloatToInt (1 000 000): time 4 ms
Для продолжения нажмите любую клавишу . . .

тестирование преобразования float в int

(int) (1 000 000): time 7 ms
static_cast (1 000 000): time 6 ms
FloatToInt (1 000 000): time 4 ms
Для продолжения нажмите любую клавишу . . .

тестирование преобразования float в int

(int) (1 000 000): time 6 ms
static_cast (1 000 000): time 6 ms
FloatToInt (1 000 000): time 4 ms
Для продолжения нажмите любую клавишу . . .

тестирование преобразования float в int

(int) (1 000 000): time 4 ms
static_cast (1 000 000): time 4 ms
FloatToInt (1 000 000): time 4 ms
Для продолжения нажмите любую клавишу . . .

тестирование преобразования float в int

(int) (1 000 000): time 5 ms
static_cast (1 000 000): time 4 ms
FloatToInt (1 000 000): time 4 ms
Для продолжения нажмите любую клавишу . . .

тестирование преобразования float в int

(int) (1 000 000): time 4 ms
static_cast (1 000 000): time 4 ms
FloatToInt (1 000 000): time 3 ms
Для продолжения нажмите любую клавишу . . .

тестирование преобразования float в int

(int) (1 000 000): time 6 ms
static_cast (1 000 000): time 5 ms
FloatToInt (1 000 000): time 2 ms
Для продолжения нажмите любую клавишу . . . 
Как видно, оно и правда работает быстрее. Кстати, заметно что static_cast работает быстрее прямого преобразования (и лично для меня это немного неожиданно)
И прямо противоположный результат в debug
тестирование преобразования float в int

(int) (1 000 000): time 9 ms
static_cast (1 000 000): time 11 ms
FloatToInt (1 000 000): time 97 ms
Для продолжения нажмите любую клавишу . . .

тестирование преобразования float в int

(int) (1 000 000): time 9 ms
static_cast (1 000 000): time 12 ms
FloatToInt (1 000 000): time 56 ms
Для продолжения нажмите любую клавишу . . .
И вот здесь наша функция ужастна. Также заметно что статик-каст наоборот хуже.
Выводы делать вам - на мой взгляд  FloatToInt дает дополнительный бонус при полной оптимизации компилятором кода, а значит может быть полезен. 

3 комментария:

  1. кстати, извиняюсь за отсутствие подсветки кода. Я пытался прикрутить специальные скрипты, но они не работают:( Видать я криворукий. Может кто детально подскажет как?

    ОтветитьУдалить
  2. http://highlight.hohli.com/ - сам пользуюсь и рекомендую - очень удобная штука.
    Копируешь туда код, потом копируешь подсвеченный и тупо вставляешь в блоггер.

    ОтветитьУдалить