Например, есть цикл перевода YUY2 буфера в буфер BGR (от 100 до 900+ тысяч итераций):
OffsetBGR = 0;
while(OffsetYUY2 < VHDR->dwBufferLength){
// Read from 4-byte YUY2 block
Y1 = VHDR->lpData[OffsetYUY2++] - 16;
U = VHDR->lpData[OffsetYUY2++] - 128;
Y2 = VHDR->lpData[OffsetYUY2++] - 16;
V = VHDR->lpData[OffsetYUY2++] - 128;
// Record to 6-byte BGR block
FrameData[OffsetBGR++] = GET_B(Y1, U, V);
FrameData[OffsetBGR++] = GET_G(Y1, U, V);
FrameData[OffsetBGR++] = GET_R(Y1, U, V);
FrameData[OffsetBGR++] = GET_B(Y2, U, V);
FrameData[OffsetBGR++] = GET_G(Y2, U, V);
FrameData[OffsetBGR++] = GET_R(Y2, U, V);
}
... и есть алгоритмы получения отдельных элементов макросами:
#define CLAMP(t) ((t>255)?255:((t<0)?0:t))
// YUV to RGB
#define GET_R(Y,U,V) CLAMP(((298 * Y + 409 * V + 128) >> 8))
#define GET_G(Y,U,V) CLAMP(((298 * Y - 100 * U - 208 * V + 128) >> 8))
#define GET_B(Y,U,V) CLAMP(((298 * Y + 516 * U + 128) >> 8))
... или встраиваемыми функциями:
inline unsigned char clapm_byte(int value){return (value>255)?255:((value<0)?0:value);}
inline unsigned char R(char Y, char V){return clapm_byte((298 * Y + 409 * V + 128) >> 8);}
inline unsigned char G(char Y, char U, char V){return clapm_byte((298 * Y - 100 * U - 208 * V + 128) >> 8);}
inline unsigned char B(char Y, char U){return clapm_byte((298 * Y + 516 * U + 128) >> 8);}
Что в длинных циклах использовать эффективней с точки зрения производительности - макросы или встраиваемые функции? И нормально ли использовать inline в inline-е, если функция небольшая?
Нет никакой разницы с точки зрения производительности, так как код inline-функции в c++ на этапе компиляции вставляется туда, где она была вызвана. Тонкости, конечно, зависят от компилятора.
Разница же будет в том, что для inline
функций компилятор дополнительно генерирует некоторый код, который поможет избежать некоторых проблем, возникающих с #define
. Например:
#define addTwoSameNumbers(a) a + a
А после вы вызываете это так:
addTwoSameNumbers(++a)
И в итоге код, который добавит компилятор, будет иметь вид:
++a + ++a
И тогда переменная a
будет увеличена дважды. С inline
функциями таких проблем нет, так как об этом заботится компилятор.
Англоязычный ответ: https://stackoverflow.com/questions/3554527/whats-the-difference-in-practice-between-inline-and-define
Разнице в смысле функций нет, и компилятор уже давно научился подставлять inline-функции в точку вызова там, где это приносит выгоду.
Однако, с макросами намного проще ошибиться. Например, в ваших макросах есть типичная ошибка:
#define GET_R(Y,U,V) CLAMP(((298 * Y + 409 * V + 128) >> 8))
Представьте себе, что кто-то вызовет
GET_R(old_Y + 1, old_V + 1, old_R + 1)
Это раскроется в
CLAMP(((298 * old_Y + 1 + 409 * old_V + 1 + 128) >> 8))
Отлаживать такую ошибку будет ой как непросто, и компилятор об этом не предупредит. Поэтому имеет смысл не пользоваться макросами без крайней, реальной на то необходимости.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Как можно заменить strcpy не теряя работоспособности?
Нужно найти максимальные элементы в матрице и вывести их отдельно Код есть, но не знаю как доработать
Как при изменении значения слайдера вызывать определённый метод? Пробовал вот так, но CLion выдаёт ошибку:
Есть программаИнтересно, как сделать так, чтобы она запускалась вместе с Windows? Поместить ярлык в автозапуск не подходит