Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Оптимизация работы с константными значениями

41K
04 сентября 2008 года
Fedot
1 / / 02.09.2008
Подскажите пожлуйста, как правильнее реализовать следующее (работаю с EXIF-тегами JPEG'а).

В каждом тэге имеется специальное поле, значение которого (type_id) определяет один из типов:

BYTE = 1
ASCII = 2
SHORT = 3
LONG = 4
RATIONAL = 5
UNDEFINED = 7
SLONG = 9
SRATIONAL = 10

Каждый тип имеет свой размер tag_size (соответственно 1, 1, 2, 4, 8, 1, 4, 8).

Для получения соответствующего размера можно создать одномерный массив c этими размерами, и обращаться к нему так:

 
Код:
size = tag_sizes[tag_id];


Но тода останутся незадействанными элементы 0, 6 и 8, так как тегов с такими идентификаторами не существует. Если же создать более компактный массив из 8 элементов (по числу типов), тогда придется пихать в него структуры struct {char type_id, char type_size}, а размер типа придется выуживать перебором идентификаторов:

 
Код:
for (i = 0; i < 8; i++)
{
    if (current_type = types.type_id)
    {
        current_size = types.type_size;
        break;
    }
}


Как думаете, существует ли какое-нибудь более логичное и эффективное решение с точки зрения использования памяти, скорости работы и читаемости кода? Ведь в более общем случае при использовании первого метода незадействованных элементов массива может быть не три, а сколь угодно много.
288
04 сентября 2008 года
nikitozz
1.2K / / 09.03.2007
Как вариант - использование предположим std::map
255
04 сентября 2008 года
Dart Bobr
1.4K / / 09.04.2004
Зачем так сложно?
Не проще ли использовать такое средство языка С++ как enum?
14
04 сентября 2008 года
Phodopus
3.3K / / 19.06.2008
Незадействованными элементами 6 и 8 можно пренебречь, 0 исключить смещением индексов.
Еще можно так:
Код:
switch (tag_id)
{
  case 1:
  case 2:
  case 7:
    return 1;
  case 3:
    return 2;
  case 4:
  case 9:
    return 4;
  case 5:
  case 10:
    return 8;
  default:
    //Сделать что-нибудь гадкое
}

Компилятор такие вещи неплохо оптимизирует..
Но быстрее всего всегда таблицей
14
04 сентября 2008 года
Phodopus
3.3K / / 19.06.2008
Хочешь полный изврат, вот:
 
Код:
tag_size = (1 << (tag_id + 3) % 5) % 15;


В твоем случае сработает :D
87
04 сентября 2008 года
Kogrom
2.7K / / 02.02.2008
Автор не привел значения type_id поэтому некоторые отвечающие не могут понять вопроса
Цитата: Dart Bobr
Зачем так сложно?
Не проще ли использовать такое средство языка С++ как enum?


Как тут использовать enum?

Вернее всего будет работать с массивом, пусть даже придется пожертвовать тремя ячейками. Но тут не велика потеря - это же простые данные (char).

std::map будет менее эффективен по скорости и скорее всего и памяти займет больше. Он был бы нужен, если бы type_id - были бы, например, строками...

Цитата: Phodopus
Хочешь полный изврат, вот:
 
Код:
tag_size = (1 << (tag_id + 3) % 5) % 15;


В твоем случае сработает :D


Этот код не будет более эффективным по скорости.

14
04 сентября 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: Kogrom
Этот код не будет более эффективным по скорости.



Подтверждаю. Поэтому и назван "полным извратом". Зато красиво :)
И повторяю что "Но быстрее всего всегда таблицей" (мой пост выше)

5
04 сентября 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Kogrom
Этот код не будет более эффективным по скорости.

Зато отлично ляжет на конвеер процессора.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог