У меня есть много небольших функций, которые я хотел бы встроить, например, для проверки флагов для некоторого условия:
const COND = UInt(1<<BITS_FOR_COND)
function is_cond(flags::UInt)
return flags & COND != 0
end
Я мог бы сделать макрос:
macro IS_COND(flags::UInt)
return :(flags & COND != 0)
end
Моя мотивация - это много подобных макрофункций в коде C, с которым я работаю:
#define IS_COND(flags) ((flags) & COND)
Я неоднократно приурочил функцию, макрос, функцию, определенную с помощью @inline, и само выражение, но ни один из них не был последовательно быстрее других, чем во многих прогонах. Сгенерированный код для вызова функции в 1) и 3) намного длиннее, чем для выражения в 4), но я не знаю, как сравнивать 2), так как @code_llvm
и т.д. Не работают с другими макросами.
1) for j=1:10 @time for i::UInt=1:10000 is_cond(i); end end
2) for j=1:10 @time for i::UInt=1:10000 @IS_COND(i); end end
3) for j=1:10 @time for i::UInt=1:10000 is_cond_inlined(i); end end
4) for j=1:10 @time for i::UInt=1:10000 i & COND != 0; end end
Вопросы: Какова цель @inline
? Из редкой документации я вижу, что она добавляет символ :inline
к выражению :meta
, но что именно это делает? Есть ли причина предпочесть функцию или макрос для этой задачи?
Мое понимание заключается в том, что функция макроса C просто заменяет буквальный текст макроса во время компиляции, поэтому полученный код не имеет переходов и, следовательно, более эффективен, чем обычный вызов функции. (Безопасность - еще одна проблема, но пусть программисты знают, что они делают.) Макрос Julia имеет промежуточные шаги, такие как анализ его аргументов, поэтому для меня не очевидно, будет ли 2) быть быстрее, чем 1). Игнорируя на данный момент, что в этом случае разница в производительности пренебрежимо мала, какой метод дает самый эффективный код?